@sentry/tanstackstart-react 10.53.0 → 10.54.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 (58) hide show
  1. package/build/cjs/client/index.js +5 -26
  2. package/build/cjs/client/index.js.map +1 -1
  3. package/build/cjs/client/sdk.js +2 -9
  4. package/build/cjs/client/sdk.js.map +1 -1
  5. package/build/cjs/client/tunnelRoute.js +2 -13
  6. package/build/cjs/client/tunnelRoute.js.map +1 -1
  7. package/build/cjs/server/globalMiddleware.js +7 -21
  8. package/build/cjs/server/globalMiddleware.js.map +1 -1
  9. package/build/cjs/server/index.js +8 -29
  10. package/build/cjs/server/index.js.map +1 -1
  11. package/build/cjs/server/middleware.js +10 -66
  12. package/build/cjs/server/middleware.js.map +1 -1
  13. package/build/cjs/server/sdk.js +2 -7
  14. package/build/cjs/server/sdk.js.map +1 -1
  15. package/build/cjs/server/tunnelRoute.js +11 -31
  16. package/build/cjs/server/tunnelRoute.js.map +1 -1
  17. package/build/cjs/server/utils.js +5 -17
  18. package/build/cjs/server/utils.js.map +1 -1
  19. package/build/cjs/server/wrapFetchWithSentry.js +9 -38
  20. package/build/cjs/server/wrapFetchWithSentry.js.map +1 -1
  21. package/build/cjs/vite/autoInstrumentMiddleware.js +15 -97
  22. package/build/cjs/vite/autoInstrumentMiddleware.js.map +1 -1
  23. package/build/cjs/vite/sentryTanstackStart.js +3 -40
  24. package/build/cjs/vite/sentryTanstackStart.js.map +1 -1
  25. package/build/cjs/vite/sourceMaps.js +30 -76
  26. package/build/cjs/vite/sourceMaps.js.map +1 -1
  27. package/build/cjs/vite/tunnelRoute.js +30 -63
  28. package/build/cjs/vite/tunnelRoute.js.map +1 -1
  29. package/build/esm/client/index.js +5 -26
  30. package/build/esm/client/index.js.map +1 -1
  31. package/build/esm/client/sdk.js +2 -9
  32. package/build/esm/client/sdk.js.map +1 -1
  33. package/build/esm/client/tunnelRoute.js +2 -13
  34. package/build/esm/client/tunnelRoute.js.map +1 -1
  35. package/build/esm/package.json +1 -1
  36. package/build/esm/server/globalMiddleware.js +7 -21
  37. package/build/esm/server/globalMiddleware.js.map +1 -1
  38. package/build/esm/server/index.js +8 -29
  39. package/build/esm/server/index.js.map +1 -1
  40. package/build/esm/server/middleware.js +10 -66
  41. package/build/esm/server/middleware.js.map +1 -1
  42. package/build/esm/server/sdk.js +2 -7
  43. package/build/esm/server/sdk.js.map +1 -1
  44. package/build/esm/server/tunnelRoute.js +11 -31
  45. package/build/esm/server/tunnelRoute.js.map +1 -1
  46. package/build/esm/server/utils.js +5 -17
  47. package/build/esm/server/utils.js.map +1 -1
  48. package/build/esm/server/wrapFetchWithSentry.js +9 -38
  49. package/build/esm/server/wrapFetchWithSentry.js.map +1 -1
  50. package/build/esm/vite/autoInstrumentMiddleware.js +15 -97
  51. package/build/esm/vite/autoInstrumentMiddleware.js.map +1 -1
  52. package/build/esm/vite/sentryTanstackStart.js +3 -40
  53. package/build/esm/vite/sentryTanstackStart.js.map +1 -1
  54. package/build/esm/vite/sourceMaps.js +30 -76
  55. package/build/esm/vite/sourceMaps.js.map +1 -1
  56. package/build/esm/vite/tunnelRoute.js +30 -63
  57. package/build/esm/vite/tunnelRoute.js.map +1 -1
  58. package/package.json +5 -5
@@ -4,30 +4,6 @@ const core = require('@sentry/core');
4
4
  const node = require('@sentry/node');
5
5
  const utils = require('./utils.js');
6
6
 
7
- /**
8
- * This function can be used to wrap the server entry request handler to add tracing to server-side functionality.
9
- * You must explicitly define a server entry point in your application for this to work. This is done by passing the request handler to the `createServerEntry` function.
10
- * For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).
11
- *
12
- * @example
13
- * ```ts
14
- * import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
15
- *
16
- * import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
17
- * import type { ServerEntry } from '@tanstack/react-start/server-entry';
18
- *
19
- * const requestHandler: ServerEntry = wrapFetchWithSentry({
20
- * fetch(request: Request) {
21
- * return handler.fetch(request);
22
- * },
23
- * });
24
- *
25
- * export default serverEntry = createServerEntry(requestHandler);
26
- * ```
27
- *
28
- * @param serverEntry - request handler to wrap
29
- * @returns - wrapped request handler
30
- */
31
7
  function wrapFetchWithSentry(serverEntry) {
32
8
  if (serverEntry.fetch) {
33
9
  serverEntry.fetch = new Proxy(serverEntry.fetch, {
@@ -35,36 +11,31 @@ function wrapFetchWithSentry(serverEntry) {
35
11
  try {
36
12
  const request = args[0];
37
13
  const url = new URL(request.url);
38
- const method = request.method || 'GET';
39
-
40
- // instrument server functions
41
- if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {
14
+ const method = request.method || "GET";
15
+ if (url.pathname.includes("_serverFn") || url.pathname.includes("createServerFn")) {
42
16
  const functionSha256 = utils.extractServerFunctionSha256(url.pathname);
43
- const op = 'function.tanstackstart';
44
-
17
+ const op = "function.tanstackstart";
45
18
  const serverFunctionSpanAttributes = {
46
- [node.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',
19
+ [node.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.tanstackstart.server",
47
20
  [node.SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,
48
- 'tanstackstart.function.hash.sha256': functionSha256,
21
+ "tanstackstart.function.hash.sha256": functionSha256
49
22
  };
50
-
51
23
  return await node.startSpan(
52
24
  {
53
- op: op,
25
+ op,
54
26
  name: `${method} ${url.pathname}`,
55
- attributes: serverFunctionSpanAttributes,
27
+ attributes: serverFunctionSpanAttributes
56
28
  },
57
29
  async () => {
58
30
  return target.apply(thisArg, args);
59
- },
31
+ }
60
32
  );
61
33
  }
62
-
63
34
  return await target.apply(thisArg, args);
64
35
  } finally {
65
36
  await core.flushIfServerless();
66
37
  }
67
- },
38
+ }
68
39
  });
69
40
  }
70
41
  return serverEntry;
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { extractServerFunctionSha256 } from './utils';\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function can be used to wrap the server entry request handler to add tracing to server-side functionality.\n * You must explicitly define a server entry point in your application for this to work. This is done by passing the request handler to the `createServerEntry` function.\n * For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).\n *\n * @example\n * ```ts\n * import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';\n *\n * import handler, { createServerEntry } from '@tanstack/react-start/server-entry';\n * import type { ServerEntry } from '@tanstack/react-start/server-entry';\n *\n * const requestHandler: ServerEntry = wrapFetchWithSentry({\n * fetch(request: Request) {\n * return handler.fetch(request);\n * },\n * });\n *\n * export default serverEntry = createServerEntry(requestHandler);\n * ```\n *\n * @param serverEntry - request handler to wrap\n * @returns - wrapped request handler\n */\nexport function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry {\n if (serverEntry.fetch) {\n serverEntry.fetch = new Proxy<typeof serverEntry.fetch>(serverEntry.fetch, {\n async apply(target, thisArg, args) {\n try {\n const request: Request = args[0];\n const url = new URL(request.url);\n const method = request.method || 'GET';\n\n // instrument server functions\n if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {\n const functionSha256 = extractServerFunctionSha256(url.pathname);\n const op = 'function.tanstackstart';\n\n const serverFunctionSpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n 'tanstackstart.function.hash.sha256': functionSha256,\n };\n\n return await startSpan(\n {\n op: op,\n name: `${method} ${url.pathname}`,\n attributes: serverFunctionSpanAttributes,\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n return await target.apply(thisArg, args);\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":["extractServerFunctionSha256","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","startSpan","flushIfServerless"],"mappings":";;;;;;AAQA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB,CAAC,WAAW,EAA4B;AAC3E,EAAE,IAAI,WAAW,CAAC,KAAK,EAAE;AACzB,IAAI,WAAW,CAAC,KAAA,GAAQ,IAAI,KAAK,CAA2B,WAAW,CAAC,KAAK,EAAE;AAC/E,MAAM,MAAM,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAE;AACzC,QAAQ,IAAI;AACZ,UAAU,MAAM,OAAO,GAAY,IAAI,CAAC,CAAC,CAAC;AAC1C,UAAU,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AAC1C,UAAU,MAAM,MAAA,GAAS,OAAO,CAAC,MAAA,IAAU,KAAK;;AAEhD;AACA,UAAU,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,KAAK,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;AAC7F,YAAY,MAAM,iBAAiBA,iCAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC5E,YAAY,MAAM,EAAA,GAAK,wBAAwB;;AAE/C,YAAY,MAAM,+BAA+B;AACjD,cAAc,CAACC,qCAAgC,GAAG,oCAAoC;AACtF,cAAc,CAACC,iCAA4B,GAAG,EAAE;AAChD,cAAc,oCAAoC,EAAE,cAAc;AAClE,aAAa;;AAEb,YAAY,OAAO,MAAMC,cAAS;AAClC,cAAc;AACd,gBAAgB,EAAE,EAAE,EAAE;AACtB,gBAAgB,IAAI,EAAE,CAAC,EAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,gBAAA,UAAA,EAAA,4BAAA;AACA,eAAA;AACA,cAAA,YAAA;AACA,gBAAA,OAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,cAAA,CAAA;AACA,aAAA;AACA,UAAA;;AAEA,UAAA,OAAA,MAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,QAAA,CAAA,SAAA;AACA,UAAA,MAAAC,sBAAA,EAAA;AACA,QAAA;AACA,MAAA,CAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA,EAAA,OAAA,WAAA;AACA;;;;"}
1
+ {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { extractServerFunctionSha256 } from './utils';\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function can be used to wrap the server entry request handler to add tracing to server-side functionality.\n * You must explicitly define a server entry point in your application for this to work. This is done by passing the request handler to the `createServerEntry` function.\n * For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).\n *\n * @example\n * ```ts\n * import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';\n *\n * import handler, { createServerEntry } from '@tanstack/react-start/server-entry';\n * import type { ServerEntry } from '@tanstack/react-start/server-entry';\n *\n * const requestHandler: ServerEntry = wrapFetchWithSentry({\n * fetch(request: Request) {\n * return handler.fetch(request);\n * },\n * });\n *\n * export default serverEntry = createServerEntry(requestHandler);\n * ```\n *\n * @param serverEntry - request handler to wrap\n * @returns - wrapped request handler\n */\nexport function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry {\n if (serverEntry.fetch) {\n serverEntry.fetch = new Proxy<typeof serverEntry.fetch>(serverEntry.fetch, {\n async apply(target, thisArg, args) {\n try {\n const request: Request = args[0];\n const url = new URL(request.url);\n const method = request.method || 'GET';\n\n // instrument server functions\n if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {\n const functionSha256 = extractServerFunctionSha256(url.pathname);\n const op = 'function.tanstackstart';\n\n const serverFunctionSpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n 'tanstackstart.function.hash.sha256': functionSha256,\n };\n\n return await startSpan(\n {\n op: op,\n name: `${method} ${url.pathname}`,\n attributes: serverFunctionSpanAttributes,\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n return await target.apply(thisArg, args);\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":["extractServerFunctionSha256","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","startSpan","flushIfServerless"],"mappings":";;;;;;AAgCO,SAAS,oBAAoB,WAAA,EAAuC;AACzE,EAAA,IAAI,YAAY,KAAA,EAAO;AACrB,IAAA,WAAA,CAAY,KAAA,GAAQ,IAAI,KAAA,CAAgC,WAAA,CAAY,KAAA,EAAO;AAAA,MACzE,MAAM,KAAA,CAAM,MAAA,EAAQ,OAAA,EAAS,IAAA,EAAM;AACjC,QAAA,IAAI;AACF,UAAA,MAAM,OAAA,GAAmB,KAAK,CAAC,CAAA;AAC/B,UAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,OAAA,CAAQ,GAAG,CAAA;AAC/B,UAAA,MAAM,MAAA,GAAS,QAAQ,MAAA,IAAU,KAAA;AAGjC,UAAA,IAAI,GAAA,CAAI,SAAS,QAAA,CAAS,WAAW,KAAK,GAAA,CAAI,QAAA,CAAS,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACjF,YAAA,MAAM,cAAA,GAAiBA,iCAAA,CAA4B,GAAA,CAAI,QAAQ,CAAA;AAC/D,YAAA,MAAM,EAAA,GAAK,wBAAA;AAEX,YAAA,MAAM,4BAAA,GAA+B;AAAA,cACnC,CAACC,qCAAgC,GAAG,oCAAA;AAAA,cACpC,CAACC,iCAA4B,GAAG,EAAA;AAAA,cAChC,oCAAA,EAAsC;AAAA,aACxC;AAEA,YAAA,OAAO,MAAMC,cAAA;AAAA,cACX;AAAA,gBACE,EAAA;AAAA,gBACA,IAAA,EAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,QAAQ,CAAA,CAAA;AAAA,gBAC/B,UAAA,EAAY;AAAA,eACd;AAAA,cACA,YAAY;AACV,gBAAA,OAAO,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAA;AAAA,cACnC;AAAA,aACF;AAAA,UACF;AAEA,UAAA,OAAO,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAA;AAAA,QACzC,CAAA,SAAE;AACA,UAAA,MAAMC,sBAAA,EAAkB;AAAA,QAC1B;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,WAAA;AACT;;;;"}
@@ -1,118 +1,70 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- /**
4
- * Core function that wraps middleware arrays matching the given regex.
5
- */
6
3
  function wrapMiddlewareArrays(code, id, debug, regex) {
7
4
  const skipped = [];
8
5
  let didWrap = false;
9
-
10
6
  const transformed = code.replace(regex, (match, key, contents) => {
11
7
  const objContents = arrayToObjectShorthand(contents);
12
8
  if (objContents) {
13
9
  didWrap = true;
14
10
  if (debug) {
15
- // eslint-disable-next-line no-console
16
11
  console.log(`[Sentry] Auto-wrapping ${key} in ${id}`);
17
12
  }
18
- // Handle method call syntax like `.middleware([...])` vs object property syntax like `middleware: [...]`
19
- if (key.endsWith('(')) {
13
+ if (key.endsWith("(")) {
20
14
  return `${key}wrapMiddlewaresWithSentry(${objContents}))`;
21
15
  }
22
16
  return `${key}: wrapMiddlewaresWithSentry(${objContents})`;
23
17
  }
24
- // Track middlewares that couldn't be auto-wrapped
25
- // Skip if we matched whitespace only
26
18
  if (contents.trim()) {
27
19
  skipped.push(key);
28
20
  }
29
21
  return match;
30
22
  });
31
-
32
23
  return { code: transformed, didWrap, skipped };
33
24
  }
34
-
35
- /**
36
- * Wraps global middleware arrays (requestMiddleware, functionMiddleware) in createStart() files.
37
- */
38
25
  function wrapGlobalMiddleware(code, id, debug) {
39
26
  return wrapMiddlewareArrays(code, id, debug, /(requestMiddleware|functionMiddleware)\s*:\s*\[([^\]]*)\]/g);
40
27
  }
41
-
42
- /**
43
- * Wraps route middleware arrays in createFileRoute() files.
44
- */
45
28
  function wrapRouteMiddleware(code, id, debug) {
46
29
  return wrapMiddlewareArrays(code, id, debug, /(middleware)\s*:\s*\[([^\]]*)\]/g);
47
30
  }
48
-
49
- /**
50
- * Wraps middleware arrays in createServerFn().middleware([...]) calls.
51
- */
52
31
  function wrapServerFnMiddleware(code, id, debug) {
53
32
  return wrapMiddlewareArrays(code, id, debug, /(\.middleware\s*\()\s*\[([^\]]*)\]\s*\)/g);
54
33
  }
55
-
56
- /**
57
- * Applies a wrap function to the current state and returns the updated state.
58
- */
59
- function applyWrap(
60
- state,
61
- wrapFn,
62
- id,
63
- debug,
64
- ) {
34
+ function applyWrap(state, wrapFn, id, debug) {
65
35
  const result = wrapFn(state.code, id, debug);
66
36
  return {
67
37
  code: result.code,
68
38
  needsImport: state.needsImport || result.didWrap,
69
- skippedMiddlewares: [...state.skippedMiddlewares, ...result.skipped],
39
+ skippedMiddlewares: [...state.skippedMiddlewares, ...result.skipped]
70
40
  };
71
41
  }
72
-
73
- /**
74
- * A Vite plugin that automatically instruments TanStack Start middlewares:
75
- * - `requestMiddleware` and `functionMiddleware` arrays in `createStart()`
76
- * - `middleware` arrays in `createFileRoute()` route definitions
77
- */
78
42
  function makeAutoInstrumentMiddlewarePlugin(options = {}) {
79
43
  const { enabled = true, debug = false } = options;
80
-
81
44
  return {
82
- name: 'sentry-tanstack-middleware-auto-instrument',
83
- enforce: 'pre',
84
-
45
+ name: "sentry-tanstack-middleware-auto-instrument",
46
+ enforce: "pre",
85
47
  transform(code, id) {
86
48
  if (!enabled) {
87
49
  return null;
88
50
  }
89
-
90
- // Skip if not a TS/JS file
91
51
  if (!/\.(ts|tsx|js|jsx|mjs|mts)$/.test(id)) {
92
52
  return null;
93
53
  }
94
-
95
- // Detect file types that should be instrumented
96
- const isStartFile = id.includes('start') && code.includes('createStart(');
97
- const isRouteFile = code.includes('createFileRoute(') && /middleware\s*:\s*\[/.test(code);
98
- const isServerFnFile = code.includes('createServerFn') && /\.middleware\s*\(\s*\[/.test(code);
99
-
54
+ const isStartFile = id.includes("start") && code.includes("createStart(");
55
+ const isRouteFile = code.includes("createFileRoute(") && /middleware\s*:\s*\[/.test(code);
56
+ const isServerFnFile = code.includes("createServerFn") && /\.middleware\s*\(\s*\[/.test(code);
100
57
  if (!isStartFile && !isRouteFile && !isServerFnFile) {
101
58
  return null;
102
59
  }
103
-
104
- // Skip if the user already did some manual wrapping
105
- if (code.includes('wrapMiddlewaresWithSentry')) {
60
+ if (code.includes("wrapMiddlewaresWithSentry")) {
106
61
  return null;
107
62
  }
108
-
109
63
  let fileTransformState = {
110
64
  code,
111
65
  needsImport: false,
112
- skippedMiddlewares: [],
66
+ skippedMiddlewares: []
113
67
  };
114
-
115
- // Wrap middlewares
116
68
  if (isStartFile) {
117
69
  fileTransformState = applyWrap(fileTransformState, wrapGlobalMiddleware, id, debug);
118
70
  }
@@ -122,70 +74,36 @@ function makeAutoInstrumentMiddlewarePlugin(options = {}) {
122
74
  if (isServerFnFile) {
123
75
  fileTransformState = applyWrap(fileTransformState, wrapServerFnMiddleware, id, debug);
124
76
  }
125
-
126
- // Warn about middlewares that couldn't be auto-wrapped
127
77
  if (fileTransformState.skippedMiddlewares.length > 0) {
128
- // eslint-disable-next-line no-console
129
78
  console.warn(
130
- `[Sentry] Could not auto-instrument ${fileTransformState.skippedMiddlewares.join(' and ')} in ${id}. ` +
131
- 'To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. ',
79
+ `[Sentry] Could not auto-instrument ${fileTransformState.skippedMiddlewares.join(" and ")} in ${id}. To instrument these middlewares, use wrapMiddlewaresWithSentry() manually. `
132
80
  );
133
81
  }
134
-
135
- // We didn't wrap any middlewares, so we don't need to import the wrapMiddlewaresWithSentry function
136
82
  if (!fileTransformState.needsImport) {
137
83
  return null;
138
84
  }
139
-
140
85
  return { code: addSentryImport(fileTransformState.code), map: null };
141
- },
86
+ }
142
87
  };
143
88
  }
144
-
145
- /**
146
- * Convert array contents to object shorthand syntax.
147
- * e.g., "foo, bar, baz" → "{ foo, bar, baz }"
148
- *
149
- * Returns null if contents contain non-identifier expressions (function calls, etc.)
150
- * which cannot be converted to object shorthand.
151
- */
152
89
  function arrayToObjectShorthand(contents) {
153
- const items = contents
154
- .split(',')
155
- .map(s => s.trim())
156
- .filter(Boolean);
157
-
158
- // Only convert if all items are valid identifiers (no complex expressions)
159
- const allIdentifiers = items.every(item => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));
90
+ const items = contents.split(",").map((s) => s.trim()).filter(Boolean);
91
+ const allIdentifiers = items.every((item) => /^[a-zA-Z_$][a-zA-Z0-9_$]*$/.test(item));
160
92
  if (!allIdentifiers || items.length === 0) {
161
93
  return null;
162
94
  }
163
-
164
- // Deduplicate to avoid invalid syntax like { foo, foo }
165
95
  const uniqueItems = [...new Set(items)];
166
-
167
- return `{ ${uniqueItems.join(', ')} }`;
96
+ return `{ ${uniqueItems.join(", ")} }`;
168
97
  }
169
-
170
- /**
171
- * Adds the wrapMiddlewaresWithSentry import to the code.
172
- * Handles 'use client' and 'use server' directives by inserting the import after them.
173
- */
174
98
  function addSentryImport(code) {
175
99
  const sentryImport = "import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n";
176
-
177
- // Don't add the import if it already exists
178
100
  if (code.includes(sentryImport.trimEnd())) {
179
101
  return code;
180
102
  }
181
-
182
- // Check for 'use server' or 'use client' directives, these need to be before any imports
183
103
  const directiveMatch = code.match(/^(['"])use (client|server)\1;?\s*\n?/);
184
-
185
104
  if (!directiveMatch) {
186
105
  return sentryImport + code;
187
106
  }
188
-
189
107
  const directive = directiveMatch[0];
190
108
  return directive + sentryImport + code.slice(directive.length);
191
109
  }
@@ -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\ntype WrapResult = {\n code: string;\n didWrap: boolean;\n skipped: string[];\n};\n\ntype FileTransformState = {\n code: string;\n needsImport: boolean;\n skippedMiddlewares: 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 // Handle method call syntax like `.middleware([...])` vs object property syntax like `middleware: [...]`\n if (key.endsWith('(')) {\n return `${key}wrapMiddlewaresWithSentry(${objContents}))`;\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 * Wraps middleware arrays in createServerFn().middleware([...]) calls.\n */\nexport function wrapServerFnMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(\\.middleware\\s*\\()\\s*\\[([^\\]]*)\\]\\s*\\)/g);\n}\n\n/**\n * Applies a wrap function to the current state and returns the updated state.\n */\nfunction applyWrap(\n state: FileTransformState,\n wrapFn: (code: string, id: string, debug: boolean) => WrapResult,\n id: string,\n debug: boolean,\n): FileTransformState {\n const result = wrapFn(state.code, id, debug);\n return {\n code: result.code,\n needsImport: state.needsImport || result.didWrap,\n skippedMiddlewares: [...state.skippedMiddlewares, ...result.skipped],\n };\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 const isServerFnFile = code.includes('createServerFn') && /\\.middleware\\s*\\(\\s*\\[/.test(code);\n\n if (!isStartFile && !isRouteFile && !isServerFnFile) {\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 fileTransformState: FileTransformState = {\n code,\n needsImport: false,\n skippedMiddlewares: [],\n };\n\n // Wrap middlewares\n if (isStartFile) {\n fileTransformState = applyWrap(fileTransformState, wrapGlobalMiddleware, id, debug);\n }\n if (isRouteFile) {\n fileTransformState = applyWrap(fileTransformState, wrapRouteMiddleware, id, debug);\n }\n if (isServerFnFile) {\n fileTransformState = applyWrap(fileTransformState, wrapServerFnMiddleware, id, debug);\n }\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (fileTransformState.skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${fileTransformState.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 (!fileTransformState.needsImport) {\n return null;\n }\n\n return { code: addSentryImport(fileTransformState.code), 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
+ {"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\ntype FileTransformState = {\n code: string;\n needsImport: boolean;\n skippedMiddlewares: 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 // Handle method call syntax like `.middleware([...])` vs object property syntax like `middleware: [...]`\n if (key.endsWith('(')) {\n return `${key}wrapMiddlewaresWithSentry(${objContents}))`;\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 * Wraps middleware arrays in createServerFn().middleware([...]) calls.\n */\nexport function wrapServerFnMiddleware(code: string, id: string, debug: boolean): WrapResult {\n return wrapMiddlewareArrays(code, id, debug, /(\\.middleware\\s*\\()\\s*\\[([^\\]]*)\\]\\s*\\)/g);\n}\n\n/**\n * Applies a wrap function to the current state and returns the updated state.\n */\nfunction applyWrap(\n state: FileTransformState,\n wrapFn: (code: string, id: string, debug: boolean) => WrapResult,\n id: string,\n debug: boolean,\n): FileTransformState {\n const result = wrapFn(state.code, id, debug);\n return {\n code: result.code,\n needsImport: state.needsImport || result.didWrap,\n skippedMiddlewares: [...state.skippedMiddlewares, ...result.skipped],\n };\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 const isServerFnFile = code.includes('createServerFn') && /\\.middleware\\s*\\(\\s*\\[/.test(code);\n\n if (!isStartFile && !isRouteFile && !isServerFnFile) {\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 fileTransformState: FileTransformState = {\n code,\n needsImport: false,\n skippedMiddlewares: [],\n };\n\n // Wrap middlewares\n if (isStartFile) {\n fileTransformState = applyWrap(fileTransformState, wrapGlobalMiddleware, id, debug);\n }\n if (isRouteFile) {\n fileTransformState = applyWrap(fileTransformState, wrapRouteMiddleware, id, debug);\n }\n if (isServerFnFile) {\n fileTransformState = applyWrap(fileTransformState, wrapServerFnMiddleware, id, debug);\n }\n\n // Warn about middlewares that couldn't be auto-wrapped\n if (fileTransformState.skippedMiddlewares.length > 0) {\n // eslint-disable-next-line no-console\n console.warn(\n `[Sentry] Could not auto-instrument ${fileTransformState.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 (!fileTransformState.needsImport) {\n return null;\n }\n\n return { code: addSentryImport(fileTransformState.code), 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":";;AAsBA,SAAS,oBAAA,CAAqB,IAAA,EAAc,EAAA,EAAY,KAAA,EAAgB,KAAA,EAA2B;AACjG,EAAA,MAAM,UAAoB,EAAC;AAC3B,EAAA,IAAI,OAAA,GAAU,KAAA;AAEd,EAAA,MAAM,cAAc,IAAA,CAAK,OAAA,CAAQ,OAAO,CAAC,KAAA,EAAe,KAAa,QAAA,KAAqB;AACxF,IAAA,MAAM,WAAA,GAAc,uBAAuB,QAAQ,CAAA;AACnD,IAAA,IAAI,WAAA,EAAa;AACf,MAAA,OAAA,GAAU,IAAA;AACV,MAAA,IAAI,KAAA,EAAO;AAET,QAAA,OAAA,CAAQ,GAAA,CAAI,CAAA,uBAAA,EAA0B,GAAG,CAAA,IAAA,EAAO,EAAE,CAAA,CAAE,CAAA;AAAA,MACtD;AAEA,MAAA,IAAI,GAAA,CAAI,QAAA,CAAS,GAAG,CAAA,EAAG;AACrB,QAAA,OAAO,CAAA,EAAG,GAAG,CAAA,0BAAA,EAA6B,WAAW,CAAA,EAAA,CAAA;AAAA,MACvD;AACA,MAAA,OAAO,CAAA,EAAG,GAAG,CAAA,4BAAA,EAA+B,WAAW,CAAA,CAAA,CAAA;AAAA,IACzD;AAGA,IAAA,IAAI,QAAA,CAAS,MAAK,EAAG;AACnB,MAAA,OAAA,CAAQ,KAAK,GAAG,CAAA;AAAA,IAClB;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AAED,EAAA,OAAO,EAAE,IAAA,EAAM,WAAA,EAAa,OAAA,EAAS,OAAA,EAAQ;AAC/C;AAKO,SAAS,oBAAA,CAAqB,IAAA,EAAc,EAAA,EAAY,KAAA,EAA4B;AACzF,EAAA,OAAO,oBAAA,CAAqB,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,4DAA4D,CAAA;AAC3G;AAKO,SAAS,mBAAA,CAAoB,IAAA,EAAc,EAAA,EAAY,KAAA,EAA4B;AACxF,EAAA,OAAO,oBAAA,CAAqB,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,kCAAkC,CAAA;AACjF;AAKO,SAAS,sBAAA,CAAuB,IAAA,EAAc,EAAA,EAAY,KAAA,EAA4B;AAC3F,EAAA,OAAO,oBAAA,CAAqB,IAAA,EAAM,EAAA,EAAI,KAAA,EAAO,0CAA0C,CAAA;AACzF;AAKA,SAAS,SAAA,CACP,KAAA,EACA,MAAA,EACA,EAAA,EACA,KAAA,EACoB;AACpB,EAAA,MAAM,MAAA,GAAS,MAAA,CAAO,KAAA,CAAM,IAAA,EAAM,IAAI,KAAK,CAAA;AAC3C,EAAA,OAAO;AAAA,IACL,MAAM,MAAA,CAAO,IAAA;AAAA,IACb,WAAA,EAAa,KAAA,CAAM,WAAA,IAAe,MAAA,CAAO,OAAA;AAAA,IACzC,oBAAoB,CAAC,GAAG,MAAM,kBAAA,EAAoB,GAAG,OAAO,OAAO;AAAA,GACrE;AACF;AAOO,SAAS,kCAAA,CAAmC,OAAA,GAA2C,EAAC,EAAW;AACxG,EAAA,MAAM,EAAE,OAAA,GAAU,IAAA,EAAM,KAAA,GAAQ,OAAM,GAAI,OAAA;AAE1C,EAAA,OAAO;AAAA,IACL,IAAA,EAAM,4CAAA;AAAA,IACN,OAAA,EAAS,KAAA;AAAA,IAET,SAAA,CAAU,MAAM,EAAA,EAAI;AAClB,MAAA,IAAI,CAAC,OAAA,EAAS;AACZ,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,CAAC,4BAAA,CAA6B,IAAA,CAAK,EAAE,CAAA,EAAG;AAC1C,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,MAAM,cAAc,EAAA,CAAG,QAAA,CAAS,OAAO,CAAA,IAAK,IAAA,CAAK,SAAS,cAAc,CAAA;AACxE,MAAA,MAAM,cAAc,IAAA,CAAK,QAAA,CAAS,kBAAkB,CAAA,IAAK,qBAAA,CAAsB,KAAK,IAAI,CAAA;AACxF,MAAA,MAAM,iBAAiB,IAAA,CAAK,QAAA,CAAS,gBAAgB,CAAA,IAAK,wBAAA,CAAyB,KAAK,IAAI,CAAA;AAE5F,MAAA,IAAI,CAAC,WAAA,IAAe,CAAC,WAAA,IAAe,CAAC,cAAA,EAAgB;AACnD,QAAA,OAAO,IAAA;AAAA,MACT;AAGA,MAAA,IAAI,IAAA,CAAK,QAAA,CAAS,2BAA2B,CAAA,EAAG;AAC9C,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,IAAI,kBAAA,GAAyC;AAAA,QAC3C,IAAA;AAAA,QACA,WAAA,EAAa,KAAA;AAAA,QACb,oBAAoB;AAAC,OACvB;AAGA,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,kBAAA,GAAqB,SAAA,CAAU,kBAAA,EAAoB,oBAAA,EAAsB,EAAA,EAAI,KAAK,CAAA;AAAA,MACpF;AACA,MAAA,IAAI,WAAA,EAAa;AACf,QAAA,kBAAA,GAAqB,SAAA,CAAU,kBAAA,EAAoB,mBAAA,EAAqB,EAAA,EAAI,KAAK,CAAA;AAAA,MACnF;AACA,MAAA,IAAI,cAAA,EAAgB;AAClB,QAAA,kBAAA,GAAqB,SAAA,CAAU,kBAAA,EAAoB,sBAAA,EAAwB,EAAA,EAAI,KAAK,CAAA;AAAA,MACtF;AAGA,MAAA,IAAI,kBAAA,CAAmB,kBAAA,CAAmB,MAAA,GAAS,CAAA,EAAG;AAEpD,QAAA,OAAA,CAAQ,IAAA;AAAA,UACN,sCAAsC,kBAAA,CAAmB,kBAAA,CAAmB,KAAK,OAAO,CAAC,OAAO,EAAE,CAAA,6EAAA;AAAA,SAEpG;AAAA,MACF;AAGA,MAAA,IAAI,CAAC,mBAAmB,WAAA,EAAa;AACnC,QAAA,OAAO,IAAA;AAAA,MACT;AAEA,MAAA,OAAO,EAAE,IAAA,EAAM,eAAA,CAAgB,mBAAmB,IAAI,CAAA,EAAG,KAAK,IAAA,EAAK;AAAA,IACrE;AAAA,GACF;AACF;AASO,SAAS,uBAAuB,QAAA,EAAiC;AACtE,EAAA,MAAM,KAAA,GAAQ,QAAA,CACX,KAAA,CAAM,GAAG,CAAA,CACT,GAAA,CAAI,CAAA,CAAA,KAAK,CAAA,CAAE,IAAA,EAAM,CAAA,CACjB,MAAA,CAAO,OAAO,CAAA;AAGjB,EAAA,MAAM,iBAAiB,KAAA,CAAM,KAAA,CAAM,UAAQ,4BAAA,CAA6B,IAAA,CAAK,IAAI,CAAC,CAAA;AAClF,EAAA,IAAI,CAAC,cAAA,IAAkB,KAAA,CAAM,MAAA,KAAW,CAAA,EAAG;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,cAAc,CAAC,GAAG,IAAI,GAAA,CAAI,KAAK,CAAC,CAAA;AAEtC,EAAA,OAAO,CAAA,EAAA,EAAK,WAAA,CAAY,IAAA,CAAK,IAAI,CAAC,CAAA,EAAA,CAAA;AACpC;AAMO,SAAS,gBAAgB,IAAA,EAAsB;AACpD,EAAA,MAAM,YAAA,GAAe,4EAAA;AAGrB,EAAA,IAAI,IAAA,CAAK,QAAA,CAAS,YAAA,CAAa,OAAA,EAAS,CAAA,EAAG;AACzC,IAAA,OAAO,IAAA;AAAA,EACT;AAGA,EAAA,MAAM,cAAA,GAAiB,IAAA,CAAK,KAAA,CAAM,sCAAsC,CAAA;AAExE,EAAA,IAAI,CAAC,cAAA,EAAgB;AACnB,IAAA,OAAO,YAAA,GAAe,IAAA;AAAA,EACxB;AAEA,EAAA,MAAM,SAAA,GAAY,eAAe,CAAC,CAAA;AAClC,EAAA,OAAO,SAAA,GAAY,YAAA,GAAe,IAAA,CAAK,KAAA,CAAM,UAAU,MAAM,CAAA;AAC/D;;;;;;;;;"}
@@ -4,59 +4,22 @@ const autoInstrumentMiddleware = require('./autoInstrumentMiddleware.js');
4
4
  const sourceMaps = require('./sourceMaps.js');
5
5
  const tunnelRoute = require('./tunnelRoute.js');
6
6
 
7
- /**
8
- * Build-time options for the Sentry TanStack Start SDK.
9
- */
10
-
11
- /**
12
- * Vite plugins for the Sentry TanStack Start SDK.
13
- *
14
- * @example
15
- * ```typescript
16
- * // vite.config.ts
17
- * import { defineConfig } from 'vite';
18
- * import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite';
19
- * import { tanstackStart } from '@tanstack/react-start/plugin/vite';
20
- *
21
- * export default defineConfig({
22
- * plugins: [
23
- * tanstackStart(),
24
- * sentryTanstackStart({
25
- * org: 'your-org',
26
- * project: 'your-project',
27
- * }),
28
- * ],
29
- * });
30
- * ```
31
- *
32
- * @param options - Options to configure the Sentry Vite plugins
33
- * @returns An array of Vite plugins
34
- */
35
7
  function sentryTanstackStart(options = {}) {
36
- const tunnelRoutePlugin = options.tunnelRoute ? tunnelRoute.makeTunnelRoutePlugin(options.tunnelRoute, options.debug) : undefined;
37
-
38
- // only add build-time plugins in production builds
39
- if (process.env.NODE_ENV === 'development') {
8
+ const tunnelRoutePlugin = options.tunnelRoute ? tunnelRoute.makeTunnelRoutePlugin(options.tunnelRoute, options.debug) : void 0;
9
+ if (process.env.NODE_ENV === "development") {
40
10
  return tunnelRoutePlugin ? [tunnelRoutePlugin] : [];
41
11
  }
42
-
43
12
  const plugins = [...sourceMaps.makeAddSentryVitePlugin(options)];
44
-
45
13
  if (tunnelRoutePlugin) {
46
14
  plugins.push(tunnelRoutePlugin);
47
15
  }
48
-
49
- // middleware auto-instrumentation
50
16
  if (options.autoInstrumentMiddleware !== false) {
51
17
  plugins.push(autoInstrumentMiddleware.makeAutoInstrumentMiddlewarePlugin({ enabled: true, debug: options.debug }));
52
18
  }
53
-
54
- // source maps
55
- const sourceMapsDisabled = options.sourcemaps?.disable === true || options.sourcemaps?.disable === 'disable-upload';
19
+ const sourceMapsDisabled = options.sourcemaps?.disable === true || options.sourcemaps?.disable === "disable-upload";
56
20
  if (!sourceMapsDisabled) {
57
21
  plugins.push(...sourceMaps.makeEnableSourceMapsVitePlugin(options));
58
22
  }
59
-
60
23
  return plugins;
61
24
  }
62
25
 
@@ -1 +1 @@
1
- {"version":3,"file":"sentryTanstackStart.js","sources":["../../../src/vite/sentryTanstackStart.ts"],"sourcesContent":["import type { BuildTimeOptionsBase } from '@sentry/core';\nimport type { Plugin } from 'vite';\nimport { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware';\nimport { makeAddSentryVitePlugin, makeEnableSourceMapsVitePlugin } from './sourceMaps';\nimport type { TunnelRouteOptions } from './tunnelRoute';\nimport { makeTunnelRoutePlugin } from './tunnelRoute';\n\n/**\n * Build-time options for the Sentry TanStack Start SDK.\n */\nexport interface SentryTanstackStartOptions extends BuildTimeOptionsBase {\n /**\n * If this flag is `true`, the Sentry plugins will automatically instrument TanStack Start middlewares.\n *\n * This wraps global middlewares (`requestMiddleware` and `functionMiddleware`) in `createStart()` with Sentry\n * instrumentation to capture performance data.\n *\n * Set to `false` to disable automatic middleware instrumentation if you prefer to wrap middlewares manually\n * using `wrapMiddlewaresWithSentry`.\n *\n * @default true\n */\n autoInstrumentMiddleware?: boolean;\n\n /**\n * Configures a framework-managed same-origin tunnel route for Sentry envelopes.\n *\n * This creates a TanStack Start server route backed by `createSentryTunnelRoute()` and applies the resulting path\n * as the default `tunnel` option on the client.\n *\n * You can pass:\n * - `true` to generate an opaque route path per dev session or production build.\n * - `'/custom-path'` to use a fixed static route path.\n * - `{ allowedDsns, path }` for full control. If `allowedDsns` is omitted or empty, the tunnel route derives the DSN\n * from the active server Sentry client at runtime.\n *\n * If you also pass `tunnel` to `Sentry.init()`, that explicit runtime option wins and a warning is emitted because\n * the managed tunnel route is being bypassed.\n */\n tunnelRoute?: TunnelRouteOptions;\n}\n\n/**\n * Vite plugins for the Sentry TanStack Start SDK.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite';\n * import { tanstackStart } from '@tanstack/react-start/plugin/vite';\n *\n * export default defineConfig({\n * plugins: [\n * tanstackStart(),\n * sentryTanstackStart({\n * org: 'your-org',\n * project: 'your-project',\n * }),\n * ],\n * });\n * ```\n *\n * @param options - Options to configure the Sentry Vite plugins\n * @returns An array of Vite plugins\n */\nexport function sentryTanstackStart(options: SentryTanstackStartOptions = {}): Plugin[] {\n const tunnelRoutePlugin = options.tunnelRoute ? makeTunnelRoutePlugin(options.tunnelRoute, options.debug) : undefined;\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return tunnelRoutePlugin ? [tunnelRoutePlugin] : [];\n }\n\n const plugins: Plugin[] = [...makeAddSentryVitePlugin(options)];\n\n if (tunnelRoutePlugin) {\n plugins.push(tunnelRoutePlugin);\n }\n\n // middleware auto-instrumentation\n if (options.autoInstrumentMiddleware !== false) {\n plugins.push(makeAutoInstrumentMiddlewarePlugin({ enabled: true, debug: options.debug }));\n }\n\n // source maps\n const sourceMapsDisabled = options.sourcemaps?.disable === true || options.sourcemaps?.disable === 'disable-upload';\n if (!sourceMapsDisabled) {\n plugins.push(...makeEnableSourceMapsVitePlugin(options));\n }\n\n return plugins;\n}\n"],"names":["makeTunnelRoutePlugin","makeAddSentryVitePlugin","makeAutoInstrumentMiddlewarePlugin","makeEnableSourceMapsVitePlugin"],"mappings":";;;;;;AAOA;AACA;AACA;;AAiCA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB,CAAC,OAAO,GAA+B,EAAE,EAAY;AACxF,EAAE,MAAM,iBAAA,GAAoB,OAAO,CAAC,WAAA,GAAcA,iCAAqB,CAAC,OAAO,CAAC,WAAW,EAAE,OAAO,CAAC,KAAK,CAAA,GAAI,SAAS;;AAEvH;AACA,EAAE,IAAI,OAAO,CAAC,GAAG,CAAC,QAAA,KAAa,aAAa,EAAE;AAC9C,IAAI,OAAO,oBAAoB,CAAC,iBAAiB,CAAA,GAAI,EAAE;AACvD,EAAE;;AAEF,EAAE,MAAM,OAAO,GAAa,CAAC,GAAGC,kCAAuB,CAAC,OAAO,CAAC,CAAC;;AAEjE,EAAE,IAAI,iBAAiB,EAAE;AACzB,IAAI,OAAO,CAAC,IAAI,CAAC,iBAAiB,CAAC;AACnC,EAAE;;AAEF;AACA,EAAE,IAAI,OAAO,CAAC,wBAAA,KAA6B,KAAK,EAAE;AAClD,IAAI,OAAO,CAAC,IAAI,CAACC,2DAAkC,CAAC,EAAE,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,OAAO,CAAC,KAAA,EAAO,CAAC,CAAC;AAC7F,EAAE;;AAEF;AACA,EAAE,MAAM,kBAAA,GAAqB,OAAO,CAAC,UAAU,EAAE,OAAA,KAAY,IAAA,IAAQ,OAAO,CAAC,UAAU,EAAE,OAAA,KAAY,gBAAgB;AACrH,EAAE,IAAI,CAAC,kBAAkB,EAAE;AAC3B,IAAI,OAAO,CAAC,IAAI,CAAC,GAAGC,yCAA8B,CAAC,OAAO,CAAC,CAAC;AAC5D,EAAE;;AAEF,EAAE,OAAO,OAAO;AAChB;;;;"}
1
+ {"version":3,"file":"sentryTanstackStart.js","sources":["../../../src/vite/sentryTanstackStart.ts"],"sourcesContent":["import type { BuildTimeOptionsBase } from '@sentry/core';\nimport type { Plugin } from 'vite';\nimport { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware';\nimport { makeAddSentryVitePlugin, makeEnableSourceMapsVitePlugin } from './sourceMaps';\nimport type { TunnelRouteOptions } from './tunnelRoute';\nimport { makeTunnelRoutePlugin } from './tunnelRoute';\n\n/**\n * Build-time options for the Sentry TanStack Start SDK.\n */\nexport interface SentryTanstackStartOptions extends BuildTimeOptionsBase {\n /**\n * If this flag is `true`, the Sentry plugins will automatically instrument TanStack Start middlewares.\n *\n * This wraps global middlewares (`requestMiddleware` and `functionMiddleware`) in `createStart()` with Sentry\n * instrumentation to capture performance data.\n *\n * Set to `false` to disable automatic middleware instrumentation if you prefer to wrap middlewares manually\n * using `wrapMiddlewaresWithSentry`.\n *\n * @default true\n */\n autoInstrumentMiddleware?: boolean;\n\n /**\n * Configures a framework-managed same-origin tunnel route for Sentry envelopes.\n *\n * This creates a TanStack Start server route backed by `createSentryTunnelRoute()` and applies the resulting path\n * as the default `tunnel` option on the client.\n *\n * You can pass:\n * - `true` to generate an opaque route path per dev session or production build.\n * - `'/custom-path'` to use a fixed static route path.\n * - `{ allowedDsns, path }` for full control. If `allowedDsns` is omitted or empty, the tunnel route derives the DSN\n * from the active server Sentry client at runtime.\n *\n * If you also pass `tunnel` to `Sentry.init()`, that explicit runtime option wins and a warning is emitted because\n * the managed tunnel route is being bypassed.\n */\n tunnelRoute?: TunnelRouteOptions;\n}\n\n/**\n * Vite plugins for the Sentry TanStack Start SDK.\n *\n * @example\n * ```typescript\n * // vite.config.ts\n * import { defineConfig } from 'vite';\n * import { sentryTanstackStart } from '@sentry/tanstackstart-react/vite';\n * import { tanstackStart } from '@tanstack/react-start/plugin/vite';\n *\n * export default defineConfig({\n * plugins: [\n * tanstackStart(),\n * sentryTanstackStart({\n * org: 'your-org',\n * project: 'your-project',\n * }),\n * ],\n * });\n * ```\n *\n * @param options - Options to configure the Sentry Vite plugins\n * @returns An array of Vite plugins\n */\nexport function sentryTanstackStart(options: SentryTanstackStartOptions = {}): Plugin[] {\n const tunnelRoutePlugin = options.tunnelRoute ? makeTunnelRoutePlugin(options.tunnelRoute, options.debug) : undefined;\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return tunnelRoutePlugin ? [tunnelRoutePlugin] : [];\n }\n\n const plugins: Plugin[] = [...makeAddSentryVitePlugin(options)];\n\n if (tunnelRoutePlugin) {\n plugins.push(tunnelRoutePlugin);\n }\n\n // middleware auto-instrumentation\n if (options.autoInstrumentMiddleware !== false) {\n plugins.push(makeAutoInstrumentMiddlewarePlugin({ enabled: true, debug: options.debug }));\n }\n\n // source maps\n const sourceMapsDisabled = options.sourcemaps?.disable === true || options.sourcemaps?.disable === 'disable-upload';\n if (!sourceMapsDisabled) {\n plugins.push(...makeEnableSourceMapsVitePlugin(options));\n }\n\n return plugins;\n}\n"],"names":["makeTunnelRoutePlugin","makeAddSentryVitePlugin","makeAutoInstrumentMiddlewarePlugin","makeEnableSourceMapsVitePlugin"],"mappings":";;;;;;AAkEO,SAAS,mBAAA,CAAoB,OAAA,GAAsC,EAAC,EAAa;AACtF,EAAA,MAAM,iBAAA,GAAoB,QAAQ,WAAA,GAAcA,iCAAA,CAAsB,QAAQ,WAAA,EAAa,OAAA,CAAQ,KAAK,CAAA,GAAI,MAAA;AAG5G,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,IAAA,OAAO,iBAAA,GAAoB,CAAC,iBAAiB,CAAA,GAAI,EAAC;AAAA,EACpD;AAEA,EAAA,MAAM,OAAA,GAAoB,CAAC,GAAGC,kCAAA,CAAwB,OAAO,CAAC,CAAA;AAE9D,EAAA,IAAI,iBAAA,EAAmB;AACrB,IAAA,OAAA,CAAQ,KAAK,iBAAiB,CAAA;AAAA,EAChC;AAGA,EAAA,IAAI,OAAA,CAAQ,6BAA6B,KAAA,EAAO;AAC9C,IAAA,OAAA,CAAQ,IAAA,CAAKC,4DAAmC,EAAE,OAAA,EAAS,MAAM,KAAA,EAAO,OAAA,CAAQ,KAAA,EAAO,CAAC,CAAA;AAAA,EAC1F;AAGA,EAAA,MAAM,qBAAqB,OAAA,CAAQ,UAAA,EAAY,YAAY,IAAA,IAAQ,OAAA,CAAQ,YAAY,OAAA,KAAY,gBAAA;AACnG,EAAA,IAAI,CAAC,kBAAA,EAAoB;AACvB,IAAA,OAAA,CAAQ,IAAA,CAAK,GAAGC,yCAAA,CAA+B,OAAO,CAAC,CAAA;AAAA,EACzD;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
@@ -2,9 +2,6 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const vitePlugin = require('@sentry/vite-plugin');
4
4
 
5
- /**
6
- * A Sentry plugin for adding the @sentry/vite-plugin to automatically upload source maps to Sentry.
7
- */
8
5
  function makeAddSentryVitePlugin(options) {
9
6
  const {
10
7
  applicationKey,
@@ -19,41 +16,34 @@ function makeAddSentryVitePlugin(options) {
19
16
  sentryUrl,
20
17
  silent,
21
18
  sourcemaps,
22
- telemetry,
19
+ telemetry
23
20
  } = options;
24
-
25
- // defer resolving the filesToDeleteAfterUpload until we got access to the Vite config
26
21
  let resolveFilesToDeleteAfterUpload;
27
- const filesToDeleteAfterUploadPromise = new Promise(resolve => {
22
+ const filesToDeleteAfterUploadPromise = new Promise((resolve) => {
28
23
  resolveFilesToDeleteAfterUpload = resolve;
29
24
  });
30
-
31
25
  const configPlugin = {
32
- name: 'sentry-tanstackstart-files-to-delete-after-upload-plugin',
33
- apply: 'build',
34
- enforce: 'post',
26
+ name: "sentry-tanstackstart-files-to-delete-after-upload-plugin",
27
+ apply: "build",
28
+ enforce: "post",
35
29
  config(config) {
36
30
  const userFilesToDelete = sourcemaps?.filesToDeleteAfterUpload;
37
-
38
- // Only auto-delete source maps if the user didn't configure sourcemaps at all
39
- if (typeof userFilesToDelete === 'undefined' && typeof config.build?.sourcemap === 'undefined') {
31
+ if (typeof userFilesToDelete === "undefined" && typeof config.build?.sourcemap === "undefined") {
40
32
  if (debug) {
41
- // eslint-disable-next-line no-console
42
33
  console.log(
43
- '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: ["./**/*.map"]` to delete generated source maps after they were uploaded to Sentry.',
34
+ '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: ["./**/*.map"]` to delete generated source maps after they were uploaded to Sentry.'
44
35
  );
45
36
  }
46
- resolveFilesToDeleteAfterUpload?.(['./**/*.map']);
37
+ resolveFilesToDeleteAfterUpload?.(["./**/*.map"]);
47
38
  } else {
48
39
  resolveFilesToDeleteAfterUpload?.(userFilesToDelete);
49
40
  }
50
- },
41
+ }
51
42
  };
52
-
53
43
  const sentryPlugins = vitePlugin.sentryVitePlugin({
54
44
  applicationKey,
55
45
  authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,
56
- bundleSizeOptimizations: bundleSizeOptimizations ?? undefined,
46
+ bundleSizeOptimizations: bundleSizeOptimizations ?? void 0,
57
47
  debug: debug ?? false,
58
48
  errorHandler,
59
49
  headers,
@@ -67,101 +57,65 @@ function makeAddSentryVitePlugin(options) {
67
57
  ignore: sourcemaps?.ignore,
68
58
  // BuildTimeOptionsBase types can lag behind bundler plugin options in some local setups.
69
59
  // Keep runtime support while staying resilient to type version skew.
70
- rewriteSources: (sourcemaps )?.rewriteSources ,
71
- filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise,
60
+ rewriteSources: sourcemaps?.rewriteSources,
61
+ filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise
72
62
  },
73
63
  telemetry: telemetry ?? true,
74
64
  url: sentryUrl,
75
65
  _metaOptions: {
76
66
  telemetry: {
77
- metaFramework: 'tanstackstart-react',
78
- },
79
- },
67
+ metaFramework: "tanstackstart-react"
68
+ }
69
+ }
80
70
  });
81
-
82
71
  return [configPlugin, ...sentryPlugins];
83
72
  }
84
-
85
- /**
86
- * A Sentry plugin for TanStack Start React to enable "hidden" source maps if they are unset.
87
- */
88
73
  function makeEnableSourceMapsVitePlugin(options) {
89
74
  return [
90
75
  {
91
- name: 'sentry-tanstackstart-react-source-maps',
92
- apply: 'build',
93
- enforce: 'post',
76
+ name: "sentry-tanstackstart-react-source-maps",
77
+ apply: "build",
78
+ enforce: "post",
94
79
  config(viteConfig) {
95
80
  return {
96
81
  ...viteConfig,
97
82
  build: {
98
83
  ...viteConfig.build,
99
- sourcemap: getUpdatedSourceMapSettings(viteConfig, options),
100
- },
84
+ sourcemap: getUpdatedSourceMapSettings(viteConfig, options)
85
+ }
101
86
  };
102
- },
103
- },
87
+ }
88
+ }
104
89
  ];
105
90
  }
106
-
107
- /** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)
108
- *
109
- * 1. User explicitly disabled source maps
110
- * - keep this setting (emit a warning that errors won't be unminified in Sentry)
111
- * - We won't upload anything
112
- *
113
- * 2. Users enabled source map generation (true, 'hidden', 'inline').
114
- * - keep this setting (don't do anything - like deletion - besides uploading)
115
- *
116
- * 3. Users didn't set source maps generation
117
- * - we enable 'hidden' source maps generation
118
- * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)
119
- *
120
- * --> only exported for testing
121
- */
122
- function getUpdatedSourceMapSettings(
123
- viteConfig,
124
- sentryPluginOptions,
125
- ) {
91
+ function getUpdatedSourceMapSettings(viteConfig, sentryPluginOptions) {
126
92
  viteConfig.build = viteConfig.build || {};
127
-
128
93
  const viteUserSourceMapSetting = viteConfig.build?.sourcemap;
129
- const settingKey = 'vite.build.sourcemap';
94
+ const settingKey = "vite.build.sourcemap";
130
95
  const debug = sentryPluginOptions?.debug;
131
-
132
- // Respect user source map setting if it is explicitly set
133
96
  if (viteUserSourceMapSetting === false) {
134
97
  if (debug) {
135
- // eslint-disable-next-line no-console
136
98
  console.warn(
137
- `[Sentry] Source map generation is currently disabled in your TanStack Start configuration (\`${settingKey}: false\`). Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified.`,
99
+ `[Sentry] Source map generation is currently disabled in your TanStack Start configuration (\`${settingKey}: false\`). Sentry won't override this setting. Without source maps, code snippets on the Sentry Issues page will remain minified.`
138
100
  );
139
101
  } else {
140
- // eslint-disable-next-line no-console
141
- console.warn('[Sentry] Source map generation is disabled in your TanStack Start configuration.');
102
+ console.warn("[Sentry] Source map generation is disabled in your TanStack Start configuration.");
142
103
  }
143
-
144
104
  return viteUserSourceMapSetting;
145
- } else if (viteUserSourceMapSetting && ['hidden', 'inline', true].includes(viteUserSourceMapSetting)) {
105
+ } else if (viteUserSourceMapSetting && ["hidden", "inline", true].includes(viteUserSourceMapSetting)) {
146
106
  if (debug) {
147
- // eslint-disable-next-line no-console
148
107
  console.log(
149
- `[Sentry] We discovered \`${settingKey}\` is set to \`${viteUserSourceMapSetting.toString()}\`. Sentry will keep this source map setting.`,
108
+ `[Sentry] We discovered \`${settingKey}\` is set to \`${viteUserSourceMapSetting.toString()}\`. Sentry will keep this source map setting.`
150
109
  );
151
110
  }
152
-
153
111
  return viteUserSourceMapSetting;
154
112
  }
155
-
156
- // If the user did not specify a source map setting, we enable 'hidden' by default
157
113
  if (debug) {
158
- // eslint-disable-next-line no-console
159
114
  console.log(
160
- `[Sentry] Enabled source map generation in the build options with \`${settingKey}: 'hidden'\`. The source maps will be deleted after they were uploaded to Sentry.`,
115
+ `[Sentry] Enabled source map generation in the build options with \`${settingKey}: 'hidden'\`. The source maps will be deleted after they were uploaded to Sentry.`
161
116
  );
162
117
  }
163
-
164
- return 'hidden';
118
+ return "hidden";
165
119
  }
166
120
 
167
121
  exports.getUpdatedSourceMapSettings = getUpdatedSourceMapSettings;