@sentry/nuxt 10.44.0 → 10.46.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/build/cjs/module.js +15 -10
  2. package/build/cjs/module.js.map +1 -1
  3. package/build/cjs/vite/databaseConfig.js +10 -2
  4. package/build/cjs/vite/databaseConfig.js.map +1 -1
  5. package/build/cjs/vite/sentryVitePlugin.js.map +1 -1
  6. package/build/cjs/vite/storageConfig.js +6 -2
  7. package/build/cjs/vite/storageConfig.js.map +1 -1
  8. package/build/cjs/vite/utils.js +21 -2
  9. package/build/cjs/vite/utils.js.map +1 -1
  10. package/build/esm/module.js +16 -11
  11. package/build/esm/module.js.map +1 -1
  12. package/build/esm/package.json +1 -1
  13. package/build/esm/vite/databaseConfig.js +10 -2
  14. package/build/esm/vite/databaseConfig.js.map +1 -1
  15. package/build/esm/vite/sentryVitePlugin.js.map +1 -1
  16. package/build/esm/vite/storageConfig.js +6 -2
  17. package/build/esm/vite/storageConfig.js.map +1 -1
  18. package/build/esm/vite/utils.js +21 -3
  19. package/build/esm/vite/utils.js.map +1 -1
  20. package/build/module/module.json +1 -1
  21. package/build/module/module.mjs +38 -14
  22. package/build/module/runtime/plugins/database-legacy.server.d.ts +5 -0
  23. package/build/module/runtime/plugins/database-legacy.server.js +6 -0
  24. package/build/module/runtime/plugins/database.server.d.ts +1 -1
  25. package/build/module/runtime/plugins/database.server.js +3 -147
  26. package/build/module/runtime/plugins/handler-legacy.server.d.ts +2 -0
  27. package/build/module/runtime/plugins/handler-legacy.server.js +4 -0
  28. package/build/module/runtime/plugins/handler.server.d.ts +6 -0
  29. package/build/module/runtime/plugins/handler.server.js +6 -0
  30. package/build/module/runtime/plugins/sentry.server.js +6 -29
  31. package/build/module/runtime/plugins/storage-legacy.server.d.ts +5 -0
  32. package/build/module/runtime/plugins/storage-legacy.server.js +6 -0
  33. package/build/module/runtime/plugins/storage.server.d.ts +4 -2
  34. package/build/module/runtime/plugins/storage.server.js +3 -168
  35. package/build/module/runtime/utils/database-span-data.d.ts +16 -2
  36. package/build/module/runtime/utils/instrumentDatabase.d.ts +9 -0
  37. package/build/module/runtime/utils/instrumentDatabase.js +147 -0
  38. package/build/module/runtime/utils/instrumentStorage.d.ts +7 -0
  39. package/build/module/runtime/utils/instrumentStorage.js +169 -0
  40. package/build/module/runtime/utils/patchEventHandler.d.ts +6 -0
  41. package/build/module/runtime/utils/patchEventHandler.js +25 -0
  42. package/build/types/module.d.ts.map +1 -1
  43. package/build/types/runtime/plugins/database-legacy.server.d.ts +6 -0
  44. package/build/types/runtime/plugins/database-legacy.server.d.ts.map +1 -0
  45. package/build/types/runtime/plugins/database.server.d.ts +1 -1
  46. package/build/types/runtime/plugins/database.server.d.ts.map +1 -1
  47. package/build/types/runtime/plugins/handler-legacy.server.d.ts +3 -0
  48. package/build/types/runtime/plugins/handler-legacy.server.d.ts.map +1 -0
  49. package/build/types/runtime/plugins/handler.server.d.ts +7 -0
  50. package/build/types/runtime/plugins/handler.server.d.ts.map +1 -0
  51. package/build/types/runtime/plugins/sentry.server.d.ts.map +1 -1
  52. package/build/types/runtime/plugins/storage-legacy.server.d.ts +6 -0
  53. package/build/types/runtime/plugins/storage-legacy.server.d.ts.map +1 -0
  54. package/build/types/runtime/plugins/storage.server.d.ts +4 -2
  55. package/build/types/runtime/plugins/storage.server.d.ts.map +1 -1
  56. package/build/types/runtime/utils/database-span-data.d.ts +16 -2
  57. package/build/types/runtime/utils/database-span-data.d.ts.map +1 -1
  58. package/build/types/runtime/utils/instrumentDatabase.d.ts +10 -0
  59. package/build/types/runtime/utils/instrumentDatabase.d.ts.map +1 -0
  60. package/build/types/runtime/utils/instrumentStorage.d.ts +8 -0
  61. package/build/types/runtime/utils/instrumentStorage.d.ts.map +1 -0
  62. package/build/types/runtime/utils/patchEventHandler.d.ts +7 -0
  63. package/build/types/runtime/utils/patchEventHandler.d.ts.map +1 -0
  64. package/build/types/runtime/utils.d.ts.map +1 -1
  65. package/build/types/vite/databaseConfig.d.ts +1 -1
  66. package/build/types/vite/databaseConfig.d.ts.map +1 -1
  67. package/build/types/vite/sentryVitePlugin.d.ts.map +1 -1
  68. package/build/types/vite/storageConfig.d.ts +1 -1
  69. package/build/types/vite/storageConfig.d.ts.map +1 -1
  70. package/build/types/vite/utils.d.ts +6 -1
  71. package/build/types/vite/utils.d.ts.map +1 -1
  72. package/package.json +16 -8
@@ -1,171 +1,6 @@
1
- import {
2
- captureException,
3
- debug,
4
- flushIfServerless,
5
- SEMANTIC_ATTRIBUTE_CACHE_HIT,
6
- SEMANTIC_ATTRIBUTE_CACHE_KEY,
7
- SEMANTIC_ATTRIBUTE_SENTRY_OP,
8
- SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
9
- SPAN_STATUS_ERROR,
10
- SPAN_STATUS_OK,
11
- startSpan
12
- } from "@sentry/core";
13
- import { useStorage } from "nitropack/runtime";
1
+ import { useStorage } from "nitro/storage";
14
2
  import { userStorageMounts } from "#sentry/storage-config.mjs";
15
- const CACHE_HIT_METHODS = /* @__PURE__ */ new Set(["hasItem", "getItem", "getItemRaw"]);
3
+ import { createStoragePlugin } from "../utils/instrumentStorage.js";
16
4
  export default async (_nitroApp) => {
17
- const storage = useStorage();
18
- const userMounts = new Set(userStorageMounts.map((m) => `${m}:`));
19
- debug.log("[storage] Starting to instrument storage drivers...");
20
- userMounts.add("cache:");
21
- userMounts.add("");
22
- const mounts = storage.getMounts();
23
- for (const mount of mounts) {
24
- if (!userMounts.has(mount.base)) {
25
- continue;
26
- }
27
- instrumentDriver(mount.driver, mount.base);
28
- }
29
- storage.mount = wrapStorageMount(storage);
5
+ await createStoragePlugin(useStorage, userStorageMounts);
30
6
  };
31
- function instrumentDriver(driver, mountBase) {
32
- if (driver.__sentry_instrumented__) {
33
- debug.log(`[storage] Driver already instrumented: "${driver.name}". Skipping...`);
34
- return driver;
35
- }
36
- debug.log(`[storage] Instrumenting driver: "${driver.name}" on mount: "${mountBase}"`);
37
- const methodsToInstrument = [
38
- "hasItem",
39
- "getItem",
40
- "getItemRaw",
41
- "getItems",
42
- "setItem",
43
- "setItemRaw",
44
- "setItems",
45
- "removeItem",
46
- "getKeys",
47
- "clear"
48
- ];
49
- for (const methodName of methodsToInstrument) {
50
- const original = driver[methodName];
51
- if (typeof original !== "function") {
52
- continue;
53
- }
54
- driver[methodName] = createMethodWrapper(original, methodName, driver, mountBase);
55
- }
56
- driver.__sentry_instrumented__ = true;
57
- return driver;
58
- }
59
- function createMethodWrapper(original, methodName, driver, mountBase) {
60
- return new Proxy(original, {
61
- async apply(target, thisArg, args) {
62
- const options = createSpanStartOptions(methodName, driver, mountBase, args);
63
- debug.log(`[storage] Running method: "${methodName}" on driver: "${driver.name ?? "unknown"}"`);
64
- return startSpan(options, async (span) => {
65
- try {
66
- const result = await target.apply(thisArg, args);
67
- span.setStatus({ code: SPAN_STATUS_OK });
68
- if (CACHE_HIT_METHODS.has(methodName)) {
69
- span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, isCacheHit(args[0], result));
70
- }
71
- return result;
72
- } catch (error) {
73
- span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
74
- captureException(error, {
75
- mechanism: {
76
- handled: false,
77
- type: options.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]
78
- }
79
- });
80
- throw error;
81
- } finally {
82
- await flushIfServerless();
83
- }
84
- });
85
- }
86
- });
87
- }
88
- function wrapStorageMount(storage) {
89
- const original = storage.mount;
90
- if (original.__sentry_instrumented__) {
91
- return original;
92
- }
93
- function mountWithInstrumentation(base, driver) {
94
- debug.log(`[storage] Instrumenting mount: "${base}"`);
95
- const instrumentedDriver = instrumentDriver(driver, base);
96
- return original(base, instrumentedDriver);
97
- }
98
- mountWithInstrumentation.__sentry_instrumented__ = true;
99
- return mountWithInstrumentation;
100
- }
101
- function normalizeMethodName(methodName) {
102
- return methodName.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
103
- }
104
- function isEmptyValue(value) {
105
- return value === null || value === void 0;
106
- }
107
- function createSpanStartOptions(methodName, driver, mountBase, args) {
108
- const keys = getCacheKeys(args?.[0], mountBase);
109
- const attributes = {
110
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `cache.${normalizeMethodName(methodName)}`,
111
- [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.cache.nuxt",
112
- [SEMANTIC_ATTRIBUTE_CACHE_KEY]: keys.length > 1 ? keys : keys[0],
113
- "db.operation.name": methodName,
114
- "db.collection.name": mountBase.replace(/:$/, ""),
115
- "db.system.name": driver.name ?? "unknown"
116
- };
117
- return {
118
- name: keys.join(", "),
119
- attributes
120
- };
121
- }
122
- function getCacheKeys(key, prefix) {
123
- if (Array.isArray(key)) {
124
- return key.map((k) => normalizeKey(k, prefix));
125
- }
126
- return [normalizeKey(key, prefix)];
127
- }
128
- function normalizeKey(key, prefix) {
129
- if (typeof key === "string") {
130
- return `${prefix}${key}`;
131
- }
132
- if (typeof key === "object" && key !== null && "key" in key) {
133
- return `${prefix}${key.key}`;
134
- }
135
- return `${prefix}${isEmptyValue(key) ? "" : String(key)}`;
136
- }
137
- const CACHED_FN_HANDLERS_RE = /^nitro:(functions|handlers):/i;
138
- function isCacheHit(key, value) {
139
- try {
140
- const isEmpty = isEmptyValue(value);
141
- if (isEmpty || !CACHED_FN_HANDLERS_RE.test(key)) {
142
- return !isEmpty;
143
- }
144
- return validateCacheEntry(key, JSON.parse(String(value)));
145
- } catch {
146
- return false;
147
- }
148
- }
149
- function validateCacheEntry(key, entry) {
150
- if (isEmptyValue(entry.value)) {
151
- return false;
152
- }
153
- if (Date.now() > (entry.expires || 0)) {
154
- return false;
155
- }
156
- if (isResponseCacheEntry(key, entry)) {
157
- if (entry.value.status >= 400) {
158
- return false;
159
- }
160
- if (entry.value.body === void 0) {
161
- return false;
162
- }
163
- if (entry.value.headers.etag === "undefined" || entry.value.headers["last-modified"] === "undefined") {
164
- return false;
165
- }
166
- }
167
- return true;
168
- }
169
- function isResponseCacheEntry(key, _) {
170
- return key.startsWith("nitro:handlers:");
171
- }
@@ -1,8 +1,22 @@
1
- import type { DatabaseConnectionConfig as DatabaseConfig } from 'nitropack/types';
1
+ import type { ConnectorName } from 'db0';
2
2
  export interface DatabaseSpanData {
3
3
  [key: string]: string | number | undefined;
4
4
  }
5
+ /**
6
+ * A minimal database connection configuration type compatible with both nitropack (Nitro v2) and nitro (Nitro v3+).
7
+ * Mirrors the shape of `DatabaseConnectionConfig` from both packages.
8
+ */
9
+ export interface DatabaseConnectionConfig {
10
+ connector?: ConnectorName;
11
+ options?: {
12
+ host?: string;
13
+ port?: number;
14
+ dataDir?: string;
15
+ name?: string;
16
+ [key: string]: unknown;
17
+ };
18
+ }
5
19
  /**
6
20
  * Extracts span attributes from the database configuration.
7
21
  */
8
- export declare function getDatabaseSpanData(config?: DatabaseConfig): Partial<DatabaseSpanData>;
22
+ export declare function getDatabaseSpanData(config?: DatabaseConnectionConfig): Partial<DatabaseSpanData>;
@@ -0,0 +1,9 @@
1
+ import type { Database } from 'db0';
2
+ import { type DatabaseConnectionConfig } from './database-span-data.js';
3
+ /**
4
+ * Creates the Nitro database plugin setup by instrumenting the configured database instances.
5
+ *
6
+ * Called from the version-specific plugin entry points (database.server.ts / database-legacy.server.ts)
7
+ * which supply the correct `useDatabase` import for their respective Nitro version.
8
+ */
9
+ export declare function createDatabasePlugin(useDatabase: (name: string) => Database, databaseConfig: Record<string, DatabaseConnectionConfig>): void;
@@ -0,0 +1,147 @@
1
+ import {
2
+ addBreadcrumb,
3
+ captureException,
4
+ debug,
5
+ flushIfServerless,
6
+ SEMANTIC_ATTRIBUTE_SENTRY_OP,
7
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
8
+ SPAN_STATUS_ERROR,
9
+ startSpan
10
+ } from "@sentry/core";
11
+ import { getDatabaseSpanData } from "./database-span-data.js";
12
+ const patchedStatement = /* @__PURE__ */ new WeakSet();
13
+ const SENTRY_ORIGIN = "auto.db.nuxt";
14
+ export function createDatabasePlugin(useDatabase, databaseConfig) {
15
+ try {
16
+ const databaseInstances = Object.keys(databaseConfig);
17
+ debug.log("[Nitro Database Plugin]: Instrumenting databases...");
18
+ for (const instance of databaseInstances) {
19
+ debug.log("[Nitro Database Plugin]: Instrumenting database instance:", instance);
20
+ const db = useDatabase(instance);
21
+ instrumentDatabase(db, databaseConfig[instance]);
22
+ }
23
+ debug.log("[Nitro Database Plugin]: Databases instrumented.");
24
+ } catch (error) {
25
+ if (error instanceof Error && /Cannot access 'instances'/.test(error.message)) {
26
+ debug.log("[Nitro Database Plugin]: Database instrumentation skipped during build time.");
27
+ return;
28
+ }
29
+ debug.error("[Nitro Database Plugin]: Failed to instrument database:", error);
30
+ }
31
+ }
32
+ function instrumentDatabase(db, config) {
33
+ if (db.__sentry_instrumented__) {
34
+ debug.log("[Nitro Database Plugin]: Database already instrumented. Skipping...");
35
+ return;
36
+ }
37
+ const metadata = {
38
+ "db.system.name": config?.connector ?? db.dialect,
39
+ ...getDatabaseSpanData(config)
40
+ };
41
+ db.prepare = new Proxy(db.prepare, {
42
+ apply(target, thisArg, args) {
43
+ const [query] = args;
44
+ return instrumentPreparedStatement(target.apply(thisArg, args), query, metadata);
45
+ }
46
+ });
47
+ db.sql = new Proxy(db.sql, {
48
+ apply(target, thisArg, args) {
49
+ const query = args[0]?.[0] ?? "";
50
+ const opts = createStartSpanOptions(query, metadata);
51
+ return startSpan(
52
+ opts,
53
+ handleSpanStart(() => target.apply(thisArg, args))
54
+ );
55
+ }
56
+ });
57
+ db.exec = new Proxy(db.exec, {
58
+ apply(target, thisArg, args) {
59
+ return startSpan(
60
+ createStartSpanOptions(args[0], metadata),
61
+ handleSpanStart(() => target.apply(thisArg, args), { query: args[0] })
62
+ );
63
+ }
64
+ });
65
+ db.__sentry_instrumented__ = true;
66
+ }
67
+ function instrumentPreparedStatement(statement, query, data) {
68
+ statement.bind = new Proxy(statement.bind, {
69
+ apply(target, thisArg, args) {
70
+ return instrumentPreparedStatementQueries(target.apply(thisArg, args), query, data);
71
+ }
72
+ });
73
+ return instrumentPreparedStatementQueries(statement, query, data);
74
+ }
75
+ function instrumentPreparedStatementQueries(statement, query, data) {
76
+ if (patchedStatement.has(statement)) {
77
+ return statement;
78
+ }
79
+ statement.get = new Proxy(statement.get, {
80
+ apply(target, thisArg, args) {
81
+ return startSpan(
82
+ createStartSpanOptions(query, data),
83
+ handleSpanStart(() => target.apply(thisArg, args), { query })
84
+ );
85
+ }
86
+ });
87
+ statement.run = new Proxy(statement.run, {
88
+ apply(target, thisArg, args) {
89
+ return startSpan(
90
+ createStartSpanOptions(query, data),
91
+ handleSpanStart(() => target.apply(thisArg, args), { query })
92
+ );
93
+ }
94
+ });
95
+ statement.all = new Proxy(statement.all, {
96
+ apply(target, thisArg, args) {
97
+ return startSpan(
98
+ createStartSpanOptions(query, data),
99
+ handleSpanStart(() => target.apply(thisArg, args), { query })
100
+ );
101
+ }
102
+ });
103
+ patchedStatement.add(statement);
104
+ return statement;
105
+ }
106
+ function handleSpanStart(fn, breadcrumbOpts) {
107
+ return async (span) => {
108
+ try {
109
+ const result = await fn();
110
+ if (breadcrumbOpts) {
111
+ createBreadcrumb(breadcrumbOpts.query);
112
+ }
113
+ return result;
114
+ } catch (error) {
115
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
116
+ captureException(error, {
117
+ mechanism: {
118
+ handled: false,
119
+ type: SENTRY_ORIGIN
120
+ }
121
+ });
122
+ throw error;
123
+ } finally {
124
+ await flushIfServerless();
125
+ }
126
+ };
127
+ }
128
+ function createBreadcrumb(query) {
129
+ addBreadcrumb({
130
+ category: "query",
131
+ message: query,
132
+ data: {
133
+ "db.query.text": query
134
+ }
135
+ });
136
+ }
137
+ function createStartSpanOptions(query, data) {
138
+ return {
139
+ name: query,
140
+ attributes: {
141
+ "db.query.text": query,
142
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: SENTRY_ORIGIN,
143
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "db.query",
144
+ ...data
145
+ }
146
+ };
147
+ }
@@ -0,0 +1,7 @@
1
+ /**
2
+ * Creates the Nitro storage plugin setup by instrumenting all relevant storage drivers.
3
+ *
4
+ * The `useStorage` parameter is typed as `() => unknown` because nitropack (Nitro v2) and nitro (Nitro v3+) define `StorageValue` differently.
5
+ * Cast to `NitroStorage` is safe since all Nitro versions expose `getMounts()` at runtime.
6
+ */
7
+ export declare function createStoragePlugin(useStorage: () => unknown, userStorageMounts: string[]): Promise<void>;
@@ -0,0 +1,169 @@
1
+ import {
2
+ captureException,
3
+ debug,
4
+ flushIfServerless,
5
+ SEMANTIC_ATTRIBUTE_CACHE_HIT,
6
+ SEMANTIC_ATTRIBUTE_CACHE_KEY,
7
+ SEMANTIC_ATTRIBUTE_SENTRY_OP,
8
+ SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,
9
+ SPAN_STATUS_ERROR,
10
+ SPAN_STATUS_OK,
11
+ startSpan
12
+ } from "@sentry/core";
13
+ const CACHE_HIT_METHODS = /* @__PURE__ */ new Set(["hasItem", "getItem", "getItemRaw"]);
14
+ export async function createStoragePlugin(useStorage, userStorageMounts) {
15
+ const storage = useStorage();
16
+ const userMounts = new Set(userStorageMounts.map((m) => `${m}:`));
17
+ debug.log("[storage] Starting to instrument storage drivers...");
18
+ userMounts.add("cache:");
19
+ userMounts.add("");
20
+ const mounts = storage.getMounts();
21
+ for (const mount of mounts) {
22
+ if (!userMounts.has(mount.base)) {
23
+ continue;
24
+ }
25
+ instrumentDriver(mount.driver, mount.base);
26
+ }
27
+ storage.mount = wrapStorageMount(storage);
28
+ }
29
+ function instrumentDriver(driver, mountBase) {
30
+ if (driver.__sentry_instrumented__) {
31
+ debug.log(`[storage] Driver already instrumented: "${driver.name}". Skipping...`);
32
+ return driver;
33
+ }
34
+ debug.log(`[storage] Instrumenting driver: "${driver.name}" on mount: "${mountBase}"`);
35
+ const methodsToInstrument = [
36
+ "hasItem",
37
+ "getItem",
38
+ "getItemRaw",
39
+ "getItems",
40
+ "setItem",
41
+ "setItemRaw",
42
+ "setItems",
43
+ "removeItem",
44
+ "getKeys",
45
+ "clear"
46
+ ];
47
+ for (const methodName of methodsToInstrument) {
48
+ const original = driver[methodName];
49
+ if (typeof original !== "function") {
50
+ continue;
51
+ }
52
+ driver[methodName] = createMethodWrapper(original, methodName, driver, mountBase);
53
+ }
54
+ driver.__sentry_instrumented__ = true;
55
+ return driver;
56
+ }
57
+ function createMethodWrapper(original, methodName, driver, mountBase) {
58
+ return new Proxy(original, {
59
+ async apply(target, thisArg, args) {
60
+ const options = createSpanStartOptions(methodName, driver, mountBase, args);
61
+ debug.log(`[storage] Running method: "${methodName}" on driver: "${driver.name ?? "unknown"}"`);
62
+ return startSpan(options, async (span) => {
63
+ try {
64
+ const result = await target.apply(thisArg, args);
65
+ span.setStatus({ code: SPAN_STATUS_OK });
66
+ if (CACHE_HIT_METHODS.has(methodName)) {
67
+ span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, isCacheHit(args[0], result));
68
+ }
69
+ return result;
70
+ } catch (error) {
71
+ span.setStatus({ code: SPAN_STATUS_ERROR, message: "internal_error" });
72
+ captureException(error, {
73
+ mechanism: {
74
+ handled: false,
75
+ type: options.attributes?.[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]
76
+ }
77
+ });
78
+ throw error;
79
+ } finally {
80
+ await flushIfServerless();
81
+ }
82
+ });
83
+ }
84
+ });
85
+ }
86
+ function wrapStorageMount(storage) {
87
+ const original = storage.mount;
88
+ if (original.__sentry_instrumented__) {
89
+ return original;
90
+ }
91
+ function mountWithInstrumentation(base, driver) {
92
+ debug.log(`[storage] Instrumenting mount: "${base}"`);
93
+ const instrumentedDriver = instrumentDriver(driver, base);
94
+ return original(base, instrumentedDriver);
95
+ }
96
+ mountWithInstrumentation.__sentry_instrumented__ = true;
97
+ return mountWithInstrumentation;
98
+ }
99
+ function normalizeMethodName(methodName) {
100
+ return methodName.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
101
+ }
102
+ function isEmptyValue(value) {
103
+ return value === null || value === void 0;
104
+ }
105
+ function createSpanStartOptions(methodName, driver, mountBase, args) {
106
+ const keys = getCacheKeys(args?.[0], mountBase);
107
+ const attributes = {
108
+ [SEMANTIC_ATTRIBUTE_SENTRY_OP]: `cache.${normalizeMethodName(methodName)}`,
109
+ [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.cache.nuxt",
110
+ [SEMANTIC_ATTRIBUTE_CACHE_KEY]: keys.length > 1 ? keys : keys[0],
111
+ "db.operation.name": methodName,
112
+ "db.collection.name": mountBase.replace(/:$/, ""),
113
+ "db.system.name": driver.name ?? "unknown"
114
+ };
115
+ return {
116
+ name: keys.join(", "),
117
+ attributes
118
+ };
119
+ }
120
+ function getCacheKeys(key, prefix) {
121
+ if (Array.isArray(key)) {
122
+ return key.map((k) => normalizeKey(k, prefix));
123
+ }
124
+ return [normalizeKey(key, prefix)];
125
+ }
126
+ function normalizeKey(key, prefix) {
127
+ if (typeof key === "string") {
128
+ return `${prefix}${key}`;
129
+ }
130
+ if (typeof key === "object" && key !== null && "key" in key) {
131
+ return `${prefix}${key.key}`;
132
+ }
133
+ return `${prefix}${isEmptyValue(key) ? "" : String(key)}`;
134
+ }
135
+ const CACHED_FN_HANDLERS_RE = /^nitro:(functions|handlers):/i;
136
+ function isCacheHit(key, value) {
137
+ try {
138
+ const isEmpty = isEmptyValue(value);
139
+ if (isEmpty || typeof key !== "string" || !CACHED_FN_HANDLERS_RE.test(key)) {
140
+ return !isEmpty;
141
+ }
142
+ return validateCacheEntry(key, JSON.parse(String(value)));
143
+ } catch {
144
+ return false;
145
+ }
146
+ }
147
+ function validateCacheEntry(key, entry) {
148
+ if (isEmptyValue(entry.value)) {
149
+ return false;
150
+ }
151
+ if (Date.now() > (entry.expires || 0)) {
152
+ return false;
153
+ }
154
+ if (isResponseCacheEntry(key, entry)) {
155
+ if ((entry.value.status ?? 0) >= 400) {
156
+ return false;
157
+ }
158
+ if (entry.value.body === void 0) {
159
+ return false;
160
+ }
161
+ if (entry.value.headers?.etag === "undefined" || entry.value.headers?.["last-modified"] === "undefined") {
162
+ return false;
163
+ }
164
+ }
165
+ return true;
166
+ }
167
+ function isResponseCacheEntry(key, _) {
168
+ return key.startsWith("nitro:handlers:");
169
+ }
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Patches the H3 event handler of Nitro.
3
+ *
4
+ * Uses a TypeScript generic type to ensure the returned handler type fits different versions of Nitro.
5
+ */
6
+ export declare function patchEventHandler<H3EventHandler extends Function>(handler: H3EventHandler): H3EventHandler;
@@ -0,0 +1,25 @@
1
+ import {
2
+ debug,
3
+ flushIfServerless,
4
+ getDefaultIsolationScope,
5
+ getIsolationScope,
6
+ withIsolationScope
7
+ } from "@sentry/core";
8
+ export function patchEventHandler(handler) {
9
+ return new Proxy(handler, {
10
+ async apply(handlerTarget, handlerThisArg, handlerArgs) {
11
+ const isolationScope = getIsolationScope();
12
+ const newIsolationScope = isolationScope === getDefaultIsolationScope() ? isolationScope.clone() : isolationScope;
13
+ debug.log(
14
+ `Patched h3 event handler. ${isolationScope === newIsolationScope ? "Using existing" : "Created new"} isolation scope.`
15
+ );
16
+ return withIsolationScope(newIsolationScope, async () => {
17
+ try {
18
+ return await handlerTarget.apply(handlerThisArg, handlerArgs);
19
+ } finally {
20
+ await flushIfServerless();
21
+ }
22
+ });
23
+ }
24
+ });
25
+ }
@@ -1 +1 @@
1
- {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAQ9D,MAAM,MAAM,aAAa,GAAG,uBAAuB,CAAC;;AAEpD,wBA0MG"}
1
+ {"version":3,"file":"module.d.ts","sourceRoot":"","sources":["../../src/module.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,uBAAuB,EAAE,MAAM,gBAAgB,CAAC;AAQ9D,MAAM,MAAM,aAAa,GAAG,uBAAuB,CAAC;;AAEpD,wBA+MG"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Nitro plugin that instruments database calls for Nuxt v3/v4 (Nitro v2)
3
+ */
4
+ declare const _default: () => void;
5
+ export default _default;
6
+ //# sourceMappingURL=database-legacy.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"database-legacy.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/database-legacy.server.ts"],"names":[],"mappings":"AAOA;;GAEG;;AACH,wBAE4B"}
@@ -1,5 +1,5 @@
1
1
  /**
2
- * Creates a Nitro plugin that instruments the database calls.
2
+ * Nitro plugin that instruments database calls for Nuxt v5+ (Nitro v3+)
3
3
  */
4
4
  declare const _default: () => void;
5
5
  export default _default;
@@ -1 +1 @@
1
- {"version":3,"file":"database.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/database.server.ts"],"names":[],"mappings":"AAkCA;;GAEG;;AACH,wBAsB4B"}
1
+ {"version":3,"file":"database.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/database.server.ts"],"names":[],"mappings":"AAOA;;GAEG;;AACH,wBAE4B"}
@@ -0,0 +1,3 @@
1
+ declare const _default: (nitroApp: import("nitropack").NitroApp) => void;
2
+ export default _default;
3
+ //# sourceMappingURL=handler-legacy.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler-legacy.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/handler-legacy.server.ts"],"names":[],"mappings":";AAIA,wBAE4B"}
@@ -0,0 +1,7 @@
1
+ import type { NitroApp } from 'nitro/types';
2
+ /**
3
+ * This plugin patches the h3 event handler for Nuxt v5+ (Nitro v3+).
4
+ */
5
+ declare const _default: (nitroApp: NitroApp) => void;
6
+ export default _default;
7
+ //# sourceMappingURL=handler.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"handler.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/handler.server.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAkB,QAAQ,EAAE,MAAM,aAAa,CAAC;AAG5D;;GAEG;mCACwB,QAAQ;AAAnC,wBAK4B"}
@@ -1 +1 @@
1
- {"version":3,"file":"sentry.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/sentry.server.ts"],"names":[],"mappings":";AAcA,wBAwB4B"}
1
+ {"version":3,"file":"sentry.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/sentry.server.ts"],"names":[],"mappings":";AAQA,wBA6B4B"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Nitro plugin that instruments storage driver calls for Nuxt v3/v4 (Nitro v2)
3
+ */
4
+ declare const _default: (_nitroApp: import("nitropack").NitroApp) => Promise<void>;
5
+ export default _default;
6
+ //# sourceMappingURL=storage-legacy.server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"storage-legacy.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/storage-legacy.server.ts"],"names":[],"mappings":"AAMA;;GAEG;;AACH,wBAE4B"}
@@ -1,6 +1,8 @@
1
1
  /**
2
- * Creates a Nitro plugin that instruments the storage driver.
2
+ * Nitro plugin that instruments storage driver calls for Nuxt v5+ (Nitro v3+)
3
3
  */
4
- declare const _default: (_nitroApp: import("nitropack").NitroApp) => Promise<void>;
4
+ declare const _default: (_nitroApp: import("nitro/types").NitroApp & {
5
+ hooks: NonNullable<import("nitro/types").NitroApp["hooks"]>;
6
+ }) => Promise<void>;
5
7
  export default _default;
6
8
  //# sourceMappingURL=storage.server.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"storage.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/storage.server.ts"],"names":[],"mappings":"AAkCA;;GAEG;;AACH,wBA6B4B"}
1
+ {"version":3,"file":"storage.server.d.ts","sourceRoot":"","sources":["../../../../src/runtime/plugins/storage.server.ts"],"names":[],"mappings":"AAMA;;GAEG;;;;AACH,wBAE4B"}