@sentry/tanstackstart-react 10.37.0 → 10.38.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.
@@ -1,8 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const index = require('./client/index.js');
4
- const sdk = require('./client/sdk.js');
5
4
  const react = require('@sentry/react');
5
+ const sdk = require('./client/sdk.js');
6
6
 
7
7
 
8
8
 
@@ -2,10 +2,10 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const index = require('./server/index.js');
4
4
  const sentryTanstackStart = require('./vite/sentryTanstackStart.js');
5
+ const node = require('@sentry/node');
5
6
  const sdk = require('./server/sdk.js');
6
7
  const wrapFetchWithSentry = require('./server/wrapFetchWithSentry.js');
7
8
  const middleware = require('./server/middleware.js');
8
- const node = require('@sentry/node');
9
9
 
10
10
 
11
11
 
@@ -1,8 +1,51 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  /**
4
- * A Vite plugin that automatically instruments TanStack Start middlewares
5
- * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.
4
+ * Core function that wraps middleware arrays matching the given regex.
5
+ */
6
+ function wrapMiddlewareArrays(code, id, debug, regex) {
7
+ const skipped = [];
8
+ let didWrap = false;
9
+
10
+ const transformed = code.replace(regex, (match, key, contents) => {
11
+ const objContents = arrayToObjectShorthand(contents);
12
+ if (objContents) {
13
+ didWrap = true;
14
+ if (debug) {
15
+ // eslint-disable-next-line no-console
16
+ console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);
17
+ }
18
+ return `${key}: wrapMiddlewaresWithSentry(${objContents})`;
19
+ }
20
+ // Track middlewares that couldn't be auto-wrapped
21
+ // Skip if we matched whitespace only
22
+ if (contents.trim()) {
23
+ skipped.push(key);
24
+ }
25
+ return match;
26
+ });
27
+
28
+ return { code: transformed, didWrap, skipped };
29
+ }
30
+
31
+ /**
32
+ * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.
33
+ */
34
+ function wrapGlobalMiddleware(code, id, debug) {
35
+ return wrapMiddlewareArrays(code, id, debug, /(requestMiddleware|functionMiddleware)\s*:\s*\[([^\]]*)\]/g);
36
+ }
37
+
38
+ /**
39
+ * Wraps route middleware arrays in createFileRoute() files.
40
+ */
41
+ function wrapRouteMiddleware(code, id, debug) {
42
+ return wrapMiddlewareArrays(code, id, debug, /(middleware)\s*:\s*\[([^\]]*)\]/g);
43
+ }
44
+
45
+ /**
46
+ * A Vite plugin that automatically instruments TanStack Start middlewares:
47
+ * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`
48
+ * - `middleware` arrays in `createFileRoute()` route definitions
6
49
  */
7
50
  function makeAutoInstrumentMiddlewarePlugin(options = {}) {
8
51
  const { enabled = true, debug = false } = options;
@@ -21,9 +64,11 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
21
64
  return null;
22
65
  }
23
66
 
24
- // Only wrap requestMiddleware and functionMiddleware in createStart()
25
- // createStart() should always be in a file named start.ts
26
- if (!id.includes('start') || !code.includes('createStart(')) {
67
+ // Detect file types that should be instrumented
68
+ const isStartFile = id.includes('start') && code.includes('createStart(');
69
+ const isRouteFile = code.includes('createFileRoute(') && /middleware\s*:\s*\[/.test(code);
70
+
71
+ if (!isStartFile && !isRouteFile) {
27
72
  return null;
28
73
  }
29
74
 
@@ -36,26 +81,24 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
36
81
  let needsImport = false;
37
82
  const skippedMiddlewares = [];
38
83
 
39
- transformed = transformed.replace(
40
- /(requestMiddleware|functionMiddleware)\s*:\s*\[([^\]]*)\]/g,
41
- (match, key, contents) => {
42
- const objContents = arrayToObjectShorthand(contents);
43
- if (objContents) {
44
- needsImport = true;
45
- if (debug) {
46
- // eslint-disable-next-line no-console
47
- console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);
48
- }
49
- return `${key}: wrapMiddlewaresWithSentry(${objContents})`;
50
- }
51
- // Track middlewares that couldn't be auto-wrapped
52
- // Skip if we matched whitespace only
53
- if (contents.trim()) {
54
- skippedMiddlewares.push(key);
55
- }
56
- return match;
57
- },
58
- );
84
+ switch (true) {
85
+ // global middleware
86
+ case isStartFile: {
87
+ const result = wrapGlobalMiddleware(transformed, id, debug);
88
+ transformed = result.code;
89
+ needsImport = needsImport || result.didWrap;
90
+ skippedMiddlewares.push(...result.skipped);
91
+ break;
92
+ }
93
+ // route middleware
94
+ case isRouteFile: {
95
+ const result = wrapRouteMiddleware(transformed, id, debug);
96
+ transformed = result.code;
97
+ needsImport = needsImport || result.didWrap;
98
+ skippedMiddlewares.push(...result.skipped);
99
+ break;
100
+ }
101
+ }
59
102
 
60
103
  // Warn about middlewares that couldn't be auto-wrapped
61
104
  if (skippedMiddlewares.length > 0) {
@@ -71,17 +114,7 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
71
114
  return null;
72
115
  }
73
116
 
74
- const sentryImport = "import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n";
75
-
76
- // Check for 'use server' or 'use client' directives, these need to be before any imports
77
- const directiveMatch = transformed.match(/^(['"])use (client|server)\1;?\s*\n?/);
78
- if (directiveMatch) {
79
- // Insert import after the directive
80
- const directive = directiveMatch[0];
81
- transformed = directive + sentryImport + transformed.slice(directive.length);
82
- } else {
83
- transformed = sentryImport + transformed;
84
- }
117
+ transformed = addSentryImport(transformed);
85
118
 
86
119
  return { code: transformed, map: null };
87
120
  },
@@ -113,6 +146,32 @@ function arrayToObjectShorthand(contents) {
113
146
  return `{ ${uniqueItems.join(', ')} }`;
114
147
  }
115
148
 
149
+ /**
150
+ * Adds the wrapMiddlewaresWithSentry import to the code.
151
+ * Handles 'use client' and 'use server' directives by inserting the import after them.
152
+ */
153
+ function addSentryImport(code) {
154
+ const sentryImport = "import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n";
155
+
156
+ // Don't add the import if it already exists
157
+ if (code.includes(sentryImport.trimEnd())) {
158
+ return code;
159
+ }
160
+
161
+ // Check for 'use server' or 'use client' directives, these need to be before any imports
162
+ const directiveMatch = code.match(/^(['"])use (client|server)\1;?\s*\n?/);
163
+
164
+ if (!directiveMatch) {
165
+ return sentryImport + code;
166
+ }
167
+
168
+ const directive = directiveMatch[0];
169
+ return directive + sentryImport + code.slice(directive.length);
170
+ }
171
+
172
+ exports.addSentryImport = addSentryImport;
116
173
  exports.arrayToObjectShorthand = arrayToObjectShorthand;
117
174
  exports.makeAutoInstrumentMiddlewarePlugin = makeAutoInstrumentMiddlewarePlugin;
175
+ exports.wrapGlobalMiddleware = wrapGlobalMiddleware;
176
+ exports.wrapRouteMiddleware = wrapRouteMiddleware;
118
177
  //# sourceMappingURL=autoInstrumentMiddleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"autoInstrumentMiddleware.js","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\ntype AutoInstrumentMiddlewareOptions = {\n enabled?: boolean;\n debug?: boolean;\n};\n\n/**\n * A Vite plugin that automatically instruments TanStack Start middlewares\n * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.\n */\nexport function makeAutoInstrumentMiddlewarePlugin(options: AutoInstrumentMiddlewareOptions = {}): Plugin {\n const { enabled = true, debug = false } = options;\n\n return {\n name: 'sentry-tanstack-middleware-auto-instrument',\n enforce: 'pre',\n\n transform(code, id) {\n if (!enabled) {\n return null;\n }\n\n // Skip if not a TS/JS file\n if (!/\\.(ts|tsx|js|jsx|mjs|mts)$/.test(id)) {\n return null;\n }\n\n // Only wrap requestMiddleware and functionMiddleware in createStart()\n // createStart() should always be in a file named start.ts\n if (!id.includes('start') || !code.includes('createStart(')) {\n return null;\n }\n\n // Skip if the user already did some manual wrapping\n if (code.includes('wrapMiddlewaresWithSentry')) {\n return null;\n }\n\n let transformed = code;\n let needsImport = false;\n const skippedMiddlewares: string[] = [];\n\n transformed = transformed.replace(\n /(requestMiddleware|functionMiddleware)\\s*:\\s*\\[([^\\]]*)\\]/g,\n (match: string, key: string, contents: string) => {\n const objContents = arrayToObjectShorthand(contents);\n if (objContents) {\n needsImport = true;\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);\n }\n return `${key}: wrapMiddlewaresWithSentry(${objContents})`;\n }\n // Track middlewares that couldn't be auto-wrapped\n // Skip if we matched whitespace only\n if (contents.trim()) {\n skippedMiddlewares.push(key);\n }\n return match;\n },\n );\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${skippedMiddlewares.join(' and ')} in ${id}. ` +\n 'To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. ',\n );\n }\n\n // We didn't wrap any middlewares, so we don't need to import the wrapMiddlewaresWithSentry function\n if (!needsImport) {\n return null;\n }\n\n const sentryImport = \"import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\\n\";\n\n // Check for 'use server' or 'use client' directives, these need to be before any imports\n const directiveMatch = transformed.match(/^(['\"])use (client|server)\\1;?\\s*\\n?/);\n if (directiveMatch) {\n // Insert import after the directive\n const directive = directiveMatch[0];\n transformed = directive + sentryImport + transformed.slice(directive.length);\n } else {\n transformed = sentryImport + transformed;\n }\n\n return { code: transformed, map: null };\n },\n };\n}\n\n/**\n * Convert array contents to object shorthand syntax.\n * e.g., \"foo, bar, baz\" → \"{ foo, bar, baz }\"\n *\n * Returns null if contents contain non-identifier expressions (function calls, etc.)\n * which cannot be converted to object shorthand.\n */\nexport function arrayToObjectShorthand(contents: string): string | null {\n const items = contents\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n\n // Only convert if all items are valid identifiers (no complex expressions)\n const allIdentifiers = items.every(item => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));\n if (!allIdentifiers || items.length === 0) {\n return null;\n }\n\n // Deduplicate to avoid invalid syntax like { foo, foo }\n const uniqueItems = [...new Set(items)];\n\n return `{ ${uniqueItems.join(', ')} }`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"autoInstrumentMiddleware.js","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\ntype AutoInstrumentMiddlewareOptions = {\n enabled?: boolean;\n debug?: boolean;\n};\n\ntype WrapResult = {\n code: string;\n didWrap: boolean;\n skipped: string[];\n};\n\n/**\n * Core function that wraps middleware arrays matching the given regex.\n */\nfunction wrapMiddlewareArrays(code: string, id: string, debug: boolean, regex: RegExp): WrapResult {\n const skipped: string[] = [];\n let didWrap = false;\n\n const transformed = code.replace(regex, (match: string, key: string, contents: string) => {\n const objContents = arrayToObjectShorthand(contents);\n if (objContents) {\n didWrap = true;\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);\n }\n return `${key}: wrapMiddlewaresWithSentry(${objContents})`;\n }\n // Track middlewares that couldn't be auto-wrapped\n // Skip if we matched whitespace only\n if (contents.trim()) {\n skipped.push(key);\n }\n return match;\n });\n\n return { code: transformed, didWrap, skipped };\n}\n\n/**\n * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.\n */\nexport function wrapGlobalMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(requestMiddleware|functionMiddleware)\\s*:\\s*\\[([^\\]]*)\\]/g);\n}\n\n/**\n * Wraps route middleware arrays in createFileRoute() files.\n */\nexport function wrapRouteMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(middleware)\\s*:\\s*\\[([^\\]]*)\\]/g);\n}\n\n/**\n * A Vite plugin that automatically instruments TanStack Start middlewares:\n * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`\n * - `middleware` arrays in `createFileRoute()` route definitions\n */\nexport function makeAutoInstrumentMiddlewarePlugin(options: AutoInstrumentMiddlewareOptions = {}): Plugin {\n const { enabled = true, debug = false } = options;\n\n return {\n name: 'sentry-tanstack-middleware-auto-instrument',\n enforce: 'pre',\n\n transform(code, id) {\n if (!enabled) {\n return null;\n }\n\n // Skip if not a TS/JS file\n if (!/\\.(ts|tsx|js|jsx|mjs|mts)$/.test(id)) {\n return null;\n }\n\n // Detect file types that should be instrumented\n const isStartFile = id.includes('start') && code.includes('createStart(');\n const isRouteFile = code.includes('createFileRoute(') && /middleware\\s*:\\s*\\[/.test(code);\n\n if (!isStartFile && !isRouteFile) {\n return null;\n }\n\n // Skip if the user already did some manual wrapping\n if (code.includes('wrapMiddlewaresWithSentry')) {\n return null;\n }\n\n let transformed = code;\n let needsImport = false;\n const skippedMiddlewares: string[] = [];\n\n switch (true) {\n // global middleware\n case isStartFile: {\n const result = wrapGlobalMiddleware(transformed, id, debug);\n transformed = result.code;\n needsImport = needsImport || result.didWrap;\n skippedMiddlewares.push(...result.skipped);\n break;\n }\n // route middleware\n case isRouteFile: {\n const result = wrapRouteMiddleware(transformed, id, debug);\n transformed = result.code;\n needsImport = needsImport || result.didWrap;\n skippedMiddlewares.push(...result.skipped);\n break;\n }\n default:\n break;\n }\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${skippedMiddlewares.join(' and ')} in ${id}. ` +\n 'To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. ',\n );\n }\n\n // We didn't wrap any middlewares, so we don't need to import the wrapMiddlewaresWithSentry function\n if (!needsImport) {\n return null;\n }\n\n transformed = addSentryImport(transformed);\n\n return { code: transformed, map: null };\n },\n };\n}\n\n/**\n * Convert array contents to object shorthand syntax.\n * e.g., \"foo, bar, baz\" → \"{ foo, bar, baz }\"\n *\n * Returns null if contents contain non-identifier expressions (function calls, etc.)\n * which cannot be converted to object shorthand.\n */\nexport function arrayToObjectShorthand(contents: string): string | null {\n const items = contents\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n\n // Only convert if all items are valid identifiers (no complex expressions)\n const allIdentifiers = items.every(item => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));\n if (!allIdentifiers || items.length === 0) {\n return null;\n }\n\n // Deduplicate to avoid invalid syntax like { foo, foo }\n const uniqueItems = [...new Set(items)];\n\n return `{ ${uniqueItems.join(', ')} }`;\n}\n\n/**\n * Adds the wrapMiddlewaresWithSentry import to the code.\n * Handles 'use client' and 'use server' directives by inserting the import after them.\n */\nexport function addSentryImport(code: string): string {\n const sentryImport = \"import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\\n\";\n\n // Don't add the import if it already exists\n if (code.includes(sentryImport.trimEnd())) {\n return code;\n }\n\n // Check for 'use server' or 'use client' directives, these need to be before any imports\n const directiveMatch = code.match(/^(['\"])use (client|server)\\1;?\\s*\\n?/);\n\n if (!directiveMatch) {\n return sentryImport + code;\n }\n\n const directive = directiveMatch[0];\n return directive + sentryImport + code.slice(directive.length);\n}\n"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
1
  export { wrapMiddlewaresWithSentry } from './client/index.js';
2
- export { init } from './client/sdk.js';
3
2
  export * from '@sentry/react';
3
+ export { init } from './client/sdk.js';
4
4
  //# sourceMappingURL=index.client.js.map
@@ -1,7 +1,7 @@
1
1
  export { ErrorBoundary, withErrorBoundary } from './server/index.js';
2
2
  export { sentryTanstackStart } from './vite/sentryTanstackStart.js';
3
+ export * from '@sentry/node';
3
4
  export { init } from './server/sdk.js';
4
5
  export { wrapFetchWithSentry } from './server/wrapFetchWithSentry.js';
5
6
  export { wrapMiddlewaresWithSentry } from './server/middleware.js';
6
- export * from '@sentry/node';
7
7
  //# sourceMappingURL=index.server.js.map
@@ -1 +1 @@
1
- {"type":"module","version":"10.37.0","sideEffects":false}
1
+ {"type":"module","version":"10.38.0","sideEffects":false}
@@ -1,6 +1,49 @@
1
1
  /**
2
- * A Vite plugin that automatically instruments TanStack Start middlewares
3
- * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.
2
+ * Core function that wraps middleware arrays matching the given regex.
3
+ */
4
+ function wrapMiddlewareArrays(code, id, debug, regex) {
5
+ const skipped = [];
6
+ let didWrap = false;
7
+
8
+ const transformed = code.replace(regex, (match, key, contents) => {
9
+ const objContents = arrayToObjectShorthand(contents);
10
+ if (objContents) {
11
+ didWrap = true;
12
+ if (debug) {
13
+ // eslint-disable-next-line no-console
14
+ console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);
15
+ }
16
+ return `${key}: wrapMiddlewaresWithSentry(${objContents})`;
17
+ }
18
+ // Track middlewares that couldn't be auto-wrapped
19
+ // Skip if we matched whitespace only
20
+ if (contents.trim()) {
21
+ skipped.push(key);
22
+ }
23
+ return match;
24
+ });
25
+
26
+ return { code: transformed, didWrap, skipped };
27
+ }
28
+
29
+ /**
30
+ * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.
31
+ */
32
+ function wrapGlobalMiddleware(code, id, debug) {
33
+ return wrapMiddlewareArrays(code, id, debug, /(requestMiddleware|functionMiddleware)\s*:\s*\[([^\]]*)\]/g);
34
+ }
35
+
36
+ /**
37
+ * Wraps route middleware arrays in createFileRoute() files.
38
+ */
39
+ function wrapRouteMiddleware(code, id, debug) {
40
+ return wrapMiddlewareArrays(code, id, debug, /(middleware)\s*:\s*\[([^\]]*)\]/g);
41
+ }
42
+
43
+ /**
44
+ * A Vite plugin that automatically instruments TanStack Start middlewares:
45
+ * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`
46
+ * - `middleware` arrays in `createFileRoute()` route definitions
4
47
  */
5
48
  function makeAutoInstrumentMiddlewarePlugin(options = {}) {
6
49
  const { enabled = true, debug = false } = options;
@@ -19,9 +62,11 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
19
62
  return null;
20
63
  }
21
64
 
22
- // Only wrap requestMiddleware and functionMiddleware in createStart()
23
- // createStart() should always be in a file named start.ts
24
- if (!id.includes('start') || !code.includes('createStart(')) {
65
+ // Detect file types that should be instrumented
66
+ const isStartFile = id.includes('start') && code.includes('createStart(');
67
+ const isRouteFile = code.includes('createFileRoute(') && /middleware\s*:\s*\[/.test(code);
68
+
69
+ if (!isStartFile && !isRouteFile) {
25
70
  return null;
26
71
  }
27
72
 
@@ -34,26 +79,24 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
34
79
  let needsImport = false;
35
80
  const skippedMiddlewares = [];
36
81
 
37
- transformed = transformed.replace(
38
- /(requestMiddleware|functionMiddleware)\s*:\s*\[([^\]]*)\]/g,
39
- (match, key, contents) => {
40
- const objContents = arrayToObjectShorthand(contents);
41
- if (objContents) {
42
- needsImport = true;
43
- if (debug) {
44
- // eslint-disable-next-line no-console
45
- console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);
46
- }
47
- return `${key}: wrapMiddlewaresWithSentry(${objContents})`;
48
- }
49
- // Track middlewares that couldn't be auto-wrapped
50
- // Skip if we matched whitespace only
51
- if (contents.trim()) {
52
- skippedMiddlewares.push(key);
53
- }
54
- return match;
55
- },
56
- );
82
+ switch (true) {
83
+ // global middleware
84
+ case isStartFile: {
85
+ const result = wrapGlobalMiddleware(transformed, id, debug);
86
+ transformed = result.code;
87
+ needsImport = needsImport || result.didWrap;
88
+ skippedMiddlewares.push(...result.skipped);
89
+ break;
90
+ }
91
+ // route middleware
92
+ case isRouteFile: {
93
+ const result = wrapRouteMiddleware(transformed, id, debug);
94
+ transformed = result.code;
95
+ needsImport = needsImport || result.didWrap;
96
+ skippedMiddlewares.push(...result.skipped);
97
+ break;
98
+ }
99
+ }
57
100
 
58
101
  // Warn about middlewares that couldn't be auto-wrapped
59
102
  if (skippedMiddlewares.length > 0) {
@@ -69,17 +112,7 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
69
112
  return null;
70
113
  }
71
114
 
72
- const sentryImport = "import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n";
73
-
74
- // Check for 'use server' or 'use client' directives, these need to be before any imports
75
- const directiveMatch = transformed.match(/^(['"])use (client|server)\1;?\s*\n?/);
76
- if (directiveMatch) {
77
- // Insert import after the directive
78
- const directive = directiveMatch[0];
79
- transformed = directive + sentryImport + transformed.slice(directive.length);
80
- } else {
81
- transformed = sentryImport + transformed;
82
- }
115
+ transformed = addSentryImport(transformed);
83
116
 
84
117
  return { code: transformed, map: null };
85
118
  },
@@ -111,5 +144,28 @@ function arrayToObjectShorthand(contents) {
111
144
  return `{ ${uniqueItems.join(', ')} }`;
112
145
  }
113
146
 
114
- export { arrayToObjectShorthand, makeAutoInstrumentMiddlewarePlugin };
147
+ /**
148
+ * Adds the wrapMiddlewaresWithSentry import to the code.
149
+ * Handles 'use client' and 'use server' directives by inserting the import after them.
150
+ */
151
+ function addSentryImport(code) {
152
+ const sentryImport = "import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n";
153
+
154
+ // Don't add the import if it already exists
155
+ if (code.includes(sentryImport.trimEnd())) {
156
+ return code;
157
+ }
158
+
159
+ // Check for 'use server' or 'use client' directives, these need to be before any imports
160
+ const directiveMatch = code.match(/^(['"])use (client|server)\1;?\s*\n?/);
161
+
162
+ if (!directiveMatch) {
163
+ return sentryImport + code;
164
+ }
165
+
166
+ const directive = directiveMatch[0];
167
+ return directive + sentryImport + code.slice(directive.length);
168
+ }
169
+
170
+ export { addSentryImport, arrayToObjectShorthand, makeAutoInstrumentMiddlewarePlugin, wrapGlobalMiddleware, wrapRouteMiddleware };
115
171
  //# sourceMappingURL=autoInstrumentMiddleware.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"autoInstrumentMiddleware.js","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\ntype AutoInstrumentMiddlewareOptions = {\n enabled?: boolean;\n debug?: boolean;\n};\n\n/**\n * A Vite plugin that automatically instruments TanStack Start middlewares\n * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.\n */\nexport function makeAutoInstrumentMiddlewarePlugin(options: AutoInstrumentMiddlewareOptions = {}): Plugin {\n const { enabled = true, debug = false } = options;\n\n return {\n name: 'sentry-tanstack-middleware-auto-instrument',\n enforce: 'pre',\n\n transform(code, id) {\n if (!enabled) {\n return null;\n }\n\n // Skip if not a TS/JS file\n if (!/\\.(ts|tsx|js|jsx|mjs|mts)$/.test(id)) {\n return null;\n }\n\n // Only wrap requestMiddleware and functionMiddleware in createStart()\n // createStart() should always be in a file named start.ts\n if (!id.includes('start') || !code.includes('createStart(')) {\n return null;\n }\n\n // Skip if the user already did some manual wrapping\n if (code.includes('wrapMiddlewaresWithSentry')) {\n return null;\n }\n\n let transformed = code;\n let needsImport = false;\n const skippedMiddlewares: string[] = [];\n\n transformed = transformed.replace(\n /(requestMiddleware|functionMiddleware)\\s*:\\s*\\[([^\\]]*)\\]/g,\n (match: string, key: string, contents: string) => {\n const objContents = arrayToObjectShorthand(contents);\n if (objContents) {\n needsImport = true;\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);\n }\n return `${key}: wrapMiddlewaresWithSentry(${objContents})`;\n }\n // Track middlewares that couldn't be auto-wrapped\n // Skip if we matched whitespace only\n if (contents.trim()) {\n skippedMiddlewares.push(key);\n }\n return match;\n },\n );\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${skippedMiddlewares.join(' and ')} in ${id}. ` +\n 'To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. ',\n );\n }\n\n // We didn't wrap any middlewares, so we don't need to import the wrapMiddlewaresWithSentry function\n if (!needsImport) {\n return null;\n }\n\n const sentryImport = \"import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\\n\";\n\n // Check for 'use server' or 'use client' directives, these need to be before any imports\n const directiveMatch = transformed.match(/^(['\"])use (client|server)\\1;?\\s*\\n?/);\n if (directiveMatch) {\n // Insert import after the directive\n const directive = directiveMatch[0];\n transformed = directive + sentryImport + transformed.slice(directive.length);\n } else {\n transformed = sentryImport + transformed;\n }\n\n return { code: transformed, map: null };\n },\n };\n}\n\n/**\n * Convert array contents to object shorthand syntax.\n * e.g., \"foo, bar, baz\" → \"{ foo, bar, baz }\"\n *\n * Returns null if contents contain non-identifier expressions (function calls, etc.)\n * which cannot be converted to object shorthand.\n */\nexport function arrayToObjectShorthand(contents: string): string | null {\n const items = contents\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n\n // Only convert if all items are valid identifiers (no complex expressions)\n const allIdentifiers = items.every(item => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));\n if (!allIdentifiers || items.length === 0) {\n return null;\n }\n\n // Deduplicate to avoid invalid syntax like { foo, foo }\n const uniqueItems = [...new Set(items)];\n\n return `{ ${uniqueItems.join(', ')} }`;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"autoInstrumentMiddleware.js","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"sourcesContent":["import type { Plugin } from 'vite';\n\ntype AutoInstrumentMiddlewareOptions = {\n enabled?: boolean;\n debug?: boolean;\n};\n\ntype WrapResult = {\n code: string;\n didWrap: boolean;\n skipped: string[];\n};\n\n/**\n * Core function that wraps middleware arrays matching the given regex.\n */\nfunction wrapMiddlewareArrays(code: string, id: string, debug: boolean, regex: RegExp): WrapResult {\n const skipped: string[] = [];\n let didWrap = false;\n\n const transformed = code.replace(regex, (match: string, key: string, contents: string) => {\n const objContents = arrayToObjectShorthand(contents);\n if (objContents) {\n didWrap = true;\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);\n }\n return `${key}: wrapMiddlewaresWithSentry(${objContents})`;\n }\n // Track middlewares that couldn't be auto-wrapped\n // Skip if we matched whitespace only\n if (contents.trim()) {\n skipped.push(key);\n }\n return match;\n });\n\n return { code: transformed, didWrap, skipped };\n}\n\n/**\n * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.\n */\nexport function wrapGlobalMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(requestMiddleware|functionMiddleware)\\s*:\\s*\\[([^\\]]*)\\]/g);\n}\n\n/**\n * Wraps route middleware arrays in createFileRoute() files.\n */\nexport function wrapRouteMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(middleware)\\s*:\\s*\\[([^\\]]*)\\]/g);\n}\n\n/**\n * A Vite plugin that automatically instruments TanStack Start middlewares:\n * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`\n * - `middleware` arrays in `createFileRoute()` route definitions\n */\nexport function makeAutoInstrumentMiddlewarePlugin(options: AutoInstrumentMiddlewareOptions = {}): Plugin {\n const { enabled = true, debug = false } = options;\n\n return {\n name: 'sentry-tanstack-middleware-auto-instrument',\n enforce: 'pre',\n\n transform(code, id) {\n if (!enabled) {\n return null;\n }\n\n // Skip if not a TS/JS file\n if (!/\\.(ts|tsx|js|jsx|mjs|mts)$/.test(id)) {\n return null;\n }\n\n // Detect file types that should be instrumented\n const isStartFile = id.includes('start') && code.includes('createStart(');\n const isRouteFile = code.includes('createFileRoute(') && /middleware\\s*:\\s*\\[/.test(code);\n\n if (!isStartFile && !isRouteFile) {\n return null;\n }\n\n // Skip if the user already did some manual wrapping\n if (code.includes('wrapMiddlewaresWithSentry')) {\n return null;\n }\n\n let transformed = code;\n let needsImport = false;\n const skippedMiddlewares: string[] = [];\n\n switch (true) {\n // global middleware\n case isStartFile: {\n const result = wrapGlobalMiddleware(transformed, id, debug);\n transformed = result.code;\n needsImport = needsImport || result.didWrap;\n skippedMiddlewares.push(...result.skipped);\n break;\n }\n // route middleware\n case isRouteFile: {\n const result = wrapRouteMiddleware(transformed, id, debug);\n transformed = result.code;\n needsImport = needsImport || result.didWrap;\n skippedMiddlewares.push(...result.skipped);\n break;\n }\n default:\n break;\n }\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${skippedMiddlewares.join(' and ')} in ${id}. ` +\n 'To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. ',\n );\n }\n\n // We didn't wrap any middlewares, so we don't need to import the wrapMiddlewaresWithSentry function\n if (!needsImport) {\n return null;\n }\n\n transformed = addSentryImport(transformed);\n\n return { code: transformed, map: null };\n },\n };\n}\n\n/**\n * Convert array contents to object shorthand syntax.\n * e.g., \"foo, bar, baz\" → \"{ foo, bar, baz }\"\n *\n * Returns null if contents contain non-identifier expressions (function calls, etc.)\n * which cannot be converted to object shorthand.\n */\nexport function arrayToObjectShorthand(contents: string): string | null {\n const items = contents\n .split(',')\n .map(s => s.trim())\n .filter(Boolean);\n\n // Only convert if all items are valid identifiers (no complex expressions)\n const allIdentifiers = items.every(item => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));\n if (!allIdentifiers || items.length === 0) {\n return null;\n }\n\n // Deduplicate to avoid invalid syntax like { foo, foo }\n const uniqueItems = [...new Set(items)];\n\n return `{ ${uniqueItems.join(', ')} }`;\n}\n\n/**\n * Adds the wrapMiddlewaresWithSentry import to the code.\n * Handles 'use client' and 'use server' directives by inserting the import after them.\n */\nexport function addSentryImport(code: string): string {\n const sentryImport = \"import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\\n\";\n\n // Don't add the import if it already exists\n if (code.includes(sentryImport.trimEnd())) {\n return code;\n }\n\n // Check for 'use server' or 'use client' directives, these need to be before any imports\n const directiveMatch = code.match(/^(['\"])use (client|server)\\1;?\\s*\\n?/);\n\n if (!directiveMatch) {\n return sentryImport + code;\n }\n\n const directive = directiveMatch[0];\n return directive + sentryImport + code.slice(directive.length);\n}\n"],"names":[],"mappings":"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"}
@@ -3,9 +3,23 @@ type AutoInstrumentMiddlewareOptions = {
3
3
  enabled?: boolean;
4
4
  debug?: boolean;
5
5
  };
6
+ type WrapResult = {
7
+ code: string;
8
+ didWrap: boolean;
9
+ skipped: string[];
10
+ };
11
+ /**
12
+ * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.
13
+ */
14
+ export declare function wrapGlobalMiddleware(code: string, id: string, debug: boolean): WrapResult;
6
15
  /**
7
- * A Vite plugin that automatically instruments TanStack Start middlewares
8
- * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.
16
+ * Wraps route middleware arrays in createFileRoute() files.
17
+ */
18
+ export declare function wrapRouteMiddleware(code: string, id: string, debug: boolean): WrapResult;
19
+ /**
20
+ * A Vite plugin that automatically instruments TanStack Start middlewares:
21
+ * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`
22
+ * - `middleware` arrays in `createFileRoute()` route definitions
9
23
  */
10
24
  export declare function makeAutoInstrumentMiddlewarePlugin(options?: AutoInstrumentMiddlewareOptions): Plugin;
11
25
  /**
@@ -16,5 +30,10 @@ export declare function makeAutoInstrumentMiddlewarePlugin(options?: AutoInstrum
16
30
  * which cannot be converted to object shorthand.
17
31
  */
18
32
  export declare function arrayToObjectShorthand(contents: string): string | null;
33
+ /**
34
+ * Adds the wrapMiddlewaresWithSentry import to the code.
35
+ * Handles 'use client' and 'use server' directives by inserting the import after them.
36
+ */
37
+ export declare function addSentryImport(code: string): string;
19
38
  export {};
20
39
  //# sourceMappingURL=autoInstrumentMiddleware.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"autoInstrumentMiddleware.d.ts","sourceRoot":"","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,KAAK,+BAA+B,GAAG;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF;;;GAGG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,GAAE,+BAAoC,GAAG,MAAM,CAkFxG;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBtE"}
1
+ {"version":3,"file":"autoInstrumentMiddleware.d.ts","sourceRoot":"","sources":["../../../src/vite/autoInstrumentMiddleware.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,MAAM,CAAC;AAEnC,KAAK,+BAA+B,GAAG;IACrC,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,KAAK,CAAC,EAAE,OAAO,CAAC;CACjB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,MAAM,EAAE,CAAC;CACnB,CAAC;AA8BF;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,UAAU,CAEzF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,GAAG,UAAU,CAExF;AAED;;;;GAIG;AACH,wBAAgB,kCAAkC,CAAC,OAAO,GAAE,+BAAoC,GAAG,MAAM,CA0ExG;AAED;;;;;;GAMG;AACH,wBAAgB,sBAAsB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAgBtE;AAED;;;GAGG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAiBpD"}
@@ -3,9 +3,23 @@ type AutoInstrumentMiddlewareOptions = {
3
3
  enabled?: boolean;
4
4
  debug?: boolean;
5
5
  };
6
+ type WrapResult = {
7
+ code: string;
8
+ didWrap: boolean;
9
+ skipped: string[];
10
+ };
11
+ /**
12
+ * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.
13
+ */
14
+ export declare function wrapGlobalMiddleware(code: string, id: string, debug: boolean): WrapResult;
6
15
  /**
7
- * A Vite plugin that automatically instruments TanStack Start middlewares
8
- * by wrapping `requestMiddleware` and `functionMiddleware` arrays in `createStart()`.
16
+ * Wraps route middleware arrays in createFileRoute() files.
17
+ */
18
+ export declare function wrapRouteMiddleware(code: string, id: string, debug: boolean): WrapResult;
19
+ /**
20
+ * A Vite plugin that automatically instruments TanStack Start middlewares:
21
+ * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`
22
+ * - `middleware` arrays in `createFileRoute()` route definitions
9
23
  */
10
24
  export declare function makeAutoInstrumentMiddlewarePlugin(options?: AutoInstrumentMiddlewareOptions): Plugin;
11
25
  /**
@@ -16,5 +30,10 @@ export declare function makeAutoInstrumentMiddlewarePlugin(options?: AutoInstrum
16
30
  * which cannot be converted to object shorthand.
17
31
  */
18
32
  export declare function arrayToObjectShorthand(contents: string): string | null;
33
+ /**
34
+ * Adds the wrapMiddlewaresWithSentry import to the code.
35
+ * Handles 'use client' and 'use server' directives by inserting the import after them.
36
+ */
37
+ export declare function addSentryImport(code: string): string;
19
38
  export {};
20
39
  //# sourceMappingURL=autoInstrumentMiddleware.d.ts.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/tanstackstart-react",
3
- "version": "10.37.0",
3
+ "version": "10.38.0",
4
4
  "description": "Official Sentry SDK for TanStack Start React",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart-react",
@@ -52,11 +52,11 @@
52
52
  "dependencies": {
53
53
  "@opentelemetry/api": "^1.9.0",
54
54
  "@opentelemetry/semantic-conventions": "^1.37.0",
55
- "@sentry-internal/browser-utils": "10.37.0",
56
- "@sentry/core": "10.37.0",
57
- "@sentry/node": "10.37.0",
58
- "@sentry/react": "10.37.0",
59
- "@sentry/vite-plugin": "^4.7.0"
55
+ "@sentry-internal/browser-utils": "10.38.0",
56
+ "@sentry/core": "10.38.0",
57
+ "@sentry/node": "10.38.0",
58
+ "@sentry/react": "10.38.0",
59
+ "@sentry/vite-plugin": "^4.8.0"
60
60
  },
61
61
  "devDependencies": {
62
62
  "vite": "^5.4.11"