@sentry/tanstackstart-react 10.68.0 → 11.0.0-alpha.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 (57) hide show
  1. package/build/cjs/server/globalMiddleware.js +1 -1
  2. package/build/cjs/server/globalMiddleware.js.map +1 -1
  3. package/build/cjs/server/middleware.js.map +1 -1
  4. package/build/cjs/server/utils.js +3 -2
  5. package/build/cjs/server/utils.js.map +1 -1
  6. package/build/cjs/server/wrapFetchWithSentry.js +3 -3
  7. package/build/cjs/server/wrapFetchWithSentry.js.map +1 -1
  8. package/build/cjs/vite/sentryTanstackStart.js +2 -0
  9. package/build/cjs/vite/sentryTanstackStart.js.map +1 -1
  10. package/build/cjs/vite/sourceMaps.js +2 -2
  11. package/build/cjs/vite/sourceMaps.js.map +1 -1
  12. package/build/esm/package.json +1 -1
  13. package/build/esm/server/globalMiddleware.js +1 -1
  14. package/build/esm/server/globalMiddleware.js.map +1 -1
  15. package/build/esm/server/middleware.js.map +1 -1
  16. package/build/esm/server/utils.js +4 -3
  17. package/build/esm/server/utils.js.map +1 -1
  18. package/build/esm/server/wrapFetchWithSentry.js +4 -4
  19. package/build/esm/server/wrapFetchWithSentry.js.map +1 -1
  20. package/build/esm/vite/sentryTanstackStart.js +2 -0
  21. package/build/esm/vite/sentryTanstackStart.js.map +1 -1
  22. package/build/esm/vite/sourceMaps.js +1 -1
  23. package/build/esm/vite/sourceMaps.js.map +1 -1
  24. package/build/import-hook.mjs +1 -1
  25. package/build/types/index.types.d.ts +1 -0
  26. package/build/types/index.types.d.ts.map +1 -1
  27. package/build/types/server/index.d.ts.map +1 -1
  28. package/build/types/server/utils.d.ts.map +1 -1
  29. package/build/types/server/wrapFetchWithSentry.d.ts +1 -1
  30. package/build/types/server/wrapFetchWithSentry.d.ts.map +1 -1
  31. package/build/types/vite/sentryTanstackStart.d.ts.map +1 -1
  32. package/build/types/vite/sourceMaps.d.ts +1 -1
  33. package/package.json +11 -24
  34. package/build/loader-hook.mjs +0 -1
  35. package/build/types-ts3.8/client/index.d.ts +0 -35
  36. package/build/types-ts3.8/client/sdk.d.ts +0 -9
  37. package/build/types-ts3.8/client/tunnelRoute.d.ts +0 -7
  38. package/build/types-ts3.8/common/index.d.ts +0 -2
  39. package/build/types-ts3.8/common/types.d.ts +0 -76
  40. package/build/types-ts3.8/config/index.d.ts +0 -2
  41. package/build/types-ts3.8/index.client.d.ts +0 -3
  42. package/build/types-ts3.8/index.server.d.ts +0 -4
  43. package/build/types-ts3.8/index.types.d.ts +0 -33
  44. package/build/types-ts3.8/server/globalMiddleware.d.ts +0 -12
  45. package/build/types-ts3.8/server/index.d.ts +0 -28
  46. package/build/types-ts3.8/server/middleware.d.ts +0 -23
  47. package/build/types-ts3.8/server/routeParametrization.d.ts +0 -12
  48. package/build/types-ts3.8/server/sdk.d.ts +0 -6
  49. package/build/types-ts3.8/server/tunnelRoute.d.ts +0 -35
  50. package/build/types-ts3.8/server/utils.d.ts +0 -6
  51. package/build/types-ts3.8/server/wrapFetchWithSentry.d.ts +0 -29
  52. package/build/types-ts3.8/vite/autoInstrumentMiddleware.d.ts +0 -43
  53. package/build/types-ts3.8/vite/index.d.ts +0 -4
  54. package/build/types-ts3.8/vite/routePatterns.d.ts +0 -18
  55. package/build/types-ts3.8/vite/sentryTanstackStart.d.ts +0 -79
  56. package/build/types-ts3.8/vite/sourceMaps.d.ts +0 -27
  57. package/build/types-ts3.8/vite/tunnelRoute.d.ts +0 -19
@@ -22,7 +22,7 @@ function createSentryFunctionMiddlewareHandler(mechanismType) {
22
22
  }) {
23
23
  const activeSpan = core.getActiveSpan();
24
24
  const spanData = activeSpan ? core.spanToJSON(activeSpan) : void 0;
25
- if (activeSpan && spanData?.op === "function.tanstackstart") {
25
+ if (activeSpan && spanData?.origin === "auto.function.tanstackstart.server") {
26
26
  if (serverFnMeta?.name) {
27
27
  const method = spanData.description?.split(" ")[0] || "GET";
28
28
  core.updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);
@@ -1 +1 @@
1
- {"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n spanToJSON,\n updateSpanName,\n} from '@sentry/core';\nimport type { SentryGlobalFunctionMiddleware, SentryGlobalRequestMiddleware } from '../common/types';\nimport { SENTRY_INTERNAL } from './middleware';\n\ntype ServerFnMeta = {\n id?: string;\n name?: string;\n filename?: string;\n};\n\nfunction createSentryMiddlewareHandler(mechanismType: string) {\n return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\nfunction createSentryFunctionMiddlewareHandler(mechanismType: string) {\n return async function sentryFunctionMiddlewareHandler({\n next,\n serverFnMeta,\n }: {\n next: () => Promise<unknown>;\n serverFnMeta?: ServerFnMeta;\n }): Promise<unknown> {\n const activeSpan = getActiveSpan();\n const spanData = activeSpan ? spanToJSON(activeSpan) : undefined;\n if (activeSpan && spanData?.op === 'function.tanstackstart') {\n if (serverFnMeta?.name) {\n const method = spanData.description?.split(' ')[0] || 'GET';\n updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n if (serverFnMeta?.id) {\n activeSpan.setAttribute('tanstackstart.function.id', serverFnMeta.id);\n }\n if (serverFnMeta?.filename) {\n activeSpan.setAttribute('tanstackstart.function.filename', serverFnMeta.filename);\n }\n }\n\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\n/**\n * Global request middleware that captures errors from API route requests.\n * Should be added as the first entry in the `requestMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n\n options: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,\n },\n};\n\n/**\n * Global function middleware that captures errors from server function invocations.\n * Should be added as the first entry in the `functionMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n\n options: {\n server: createSentryFunctionMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (\n ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n ) => any, // eslint-disable-line @typescript-eslint/no-explicit-any\n },\n};\n\n// Mark as internal so the Vite auto-instrumentation plugin skips these middleware\naddNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);\naddNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);\n"],"names":["captureException","getActiveSpan","spanToJSON","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","addNonEnumerableProperty","SENTRY_INTERNAL"],"mappings":";;;;;AAiBA,SAAS,8BAA8B,aAAA,EAAuB;AAC5D,EAAA,OAAO,eAAe,uBAAA,CAAwB,EAAE,IAAA,EAAK,EAAuD;AAC1G,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAAA,qBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAEA,SAAS,sCAAsC,aAAA,EAAuB;AACpE,EAAA,OAAO,eAAe,+BAAA,CAAgC;AAAA,IACpD,IAAA;AAAA,IACA;AAAA,GACF,EAGqB;AACnB,IAAA,MAAM,aAAaC,kBAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAaC,eAAA,CAAW,UAAU,CAAA,GAAI,MAAA;AACvD,IAAA,IAAI,UAAA,IAAc,QAAA,EAAU,EAAA,KAAO,wBAAA,EAA0B;AAC3D,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,SAAS,QAAA,CAAS,WAAA,EAAa,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,KAAA;AACtD,QAAAC,mBAAA,CAAe,YAAY,CAAA,EAAG,MAAM,CAAA,YAAA,EAAe,YAAA,CAAa,IAAI,CAAA,CAAE,CAAA;AACtE,QAAA,UAAA,CAAW,YAAA,CAAaC,uCAAkC,OAAO,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,UAAA,CAAW,YAAA,CAAa,2BAAA,EAA6B,YAAA,CAAa,EAAE,CAAA;AAAA,MACtE;AACA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,UAAA,CAAW,YAAA,CAAa,iCAAA,EAAmC,YAAA,CAAa,QAAQ,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAAJ,qBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMO,MAAM,6BAAA,GAA+D;AAAA;AAAA,EAE1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA;AAAA,IAEP,MAAA,EAAQ,8BAA8B,uCAAuC;AAAA;AAEjF;AAMO,MAAM,8BAAA,GAAiE;AAAA;AAAA,EAE5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,sCAAsC,+CAA+C;AAAA;AAAA;AAIjG;AAGAK,6BAAA,CAAyB,6BAAA,EAA+BC,4BAAiB,IAAI,CAAA;AAC7ED,6BAAA,CAAyB,8BAAA,EAAgCC,4BAAiB,IAAI,CAAA;;;;;"}
1
+ {"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n spanToJSON,\n updateSpanName,\n} from '@sentry/core';\nimport type { SentryGlobalFunctionMiddleware, SentryGlobalRequestMiddleware } from '../common/types';\nimport { SENTRY_INTERNAL } from './middleware';\n\ntype ServerFnMeta = {\n id?: string;\n name?: string;\n filename?: string;\n};\n\nfunction createSentryMiddlewareHandler(mechanismType: string) {\n return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\nfunction createSentryFunctionMiddlewareHandler(mechanismType: string) {\n return async function sentryFunctionMiddlewareHandler({\n next,\n serverFnMeta,\n }: {\n next: () => Promise<unknown>;\n serverFnMeta?: ServerFnMeta;\n }): Promise<unknown> {\n const activeSpan = getActiveSpan();\n const spanData = activeSpan ? spanToJSON(activeSpan) : undefined;\n if (activeSpan && spanData?.origin === 'auto.function.tanstackstart.server') {\n if (serverFnMeta?.name) {\n const method = spanData.description?.split(' ')[0] || 'GET';\n updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n if (serverFnMeta?.id) {\n activeSpan.setAttribute('tanstackstart.function.id', serverFnMeta.id);\n }\n if (serverFnMeta?.filename) {\n activeSpan.setAttribute('tanstackstart.function.filename', serverFnMeta.filename);\n }\n }\n\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\n/**\n * Global request middleware that captures errors from API route requests.\n * Should be added as the first entry in the `requestMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n\n options: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,\n },\n};\n\n/**\n * Global function middleware that captures errors from server function invocations.\n * Should be added as the first entry in the `functionMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n\n options: {\n server: createSentryFunctionMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (\n ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n ) => any, // eslint-disable-line @typescript-eslint/no-explicit-any\n },\n};\n\n// Mark as internal so the Vite auto-instrumentation plugin skips these middleware\naddNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);\naddNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);\n"],"names":["captureException","getActiveSpan","spanToJSON","updateSpanName","SEMANTIC_ATTRIBUTE_SENTRY_SOURCE","addNonEnumerableProperty","SENTRY_INTERNAL"],"mappings":";;;;;AAiBA,SAAS,8BAA8B,aAAA,EAAuB;AAC5D,EAAA,OAAO,eAAe,uBAAA,CAAwB,EAAE,IAAA,EAAK,EAAuD;AAC1G,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAAA,qBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAEA,SAAS,sCAAsC,aAAA,EAAuB;AACpE,EAAA,OAAO,eAAe,+BAAA,CAAgC;AAAA,IACpD,IAAA;AAAA,IACA;AAAA,GACF,EAGqB;AACnB,IAAA,MAAM,aAAaC,kBAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAaC,eAAA,CAAW,UAAU,CAAA,GAAI,MAAA;AACvD,IAAA,IAAI,UAAA,IAAc,QAAA,EAAU,MAAA,KAAW,oCAAA,EAAsC;AAC3E,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,SAAS,QAAA,CAAS,WAAA,EAAa,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,KAAA;AACtD,QAAAC,mBAAA,CAAe,YAAY,CAAA,EAAG,MAAM,CAAA,YAAA,EAAe,YAAA,CAAa,IAAI,CAAA,CAAE,CAAA;AACtE,QAAA,UAAA,CAAW,YAAA,CAAaC,uCAAkC,OAAO,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,UAAA,CAAW,YAAA,CAAa,2BAAA,EAA6B,YAAA,CAAa,EAAE,CAAA;AAAA,MACtE;AACA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,UAAA,CAAW,YAAA,CAAa,iCAAA,EAAmC,YAAA,CAAa,QAAQ,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAAJ,qBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMO,MAAM,6BAAA,GAA+D;AAAA;AAAA,EAE1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA;AAAA,IAEP,MAAA,EAAQ,8BAA8B,uCAAuC;AAAA;AAEjF;AAMO,MAAM,8BAAA,GAAiE;AAAA;AAAA,EAE5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,sCAAsC,+CAA+C;AAAA;AAAA;AAIjG;AAGAK,6BAAA,CAAyB,6BAAA,EAA+BC,4BAAiB,IAAI,CAAA;AAC7ED,6BAAA,CAAyB,8BAAA,EAAgCC,4BAAiB,IAAI,CAAA;;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { isObjectLike, addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (isObjectLike(middlewareArgs) && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware as unknown as Record<string, unknown>, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":["withActiveSpan","getActiveSpan","startSpanManual","getMiddlewareSpanOptions","isObjectLike","addNonEnumerableProperty"],"mappings":";;;;;;AAMA,MAAM,cAAA,GAAiB,oBAAA;AAChB,MAAM,eAAA,GAAkB;AAM/B,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,QAAA,EACA,SAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,KAAA,EAAO,CAAC,YAAA,EAAc,WAAA,EAAa,QAAA,KAAa;AAC9C,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,IAAA,CAAK,GAAA,EAAI;AAET,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAOA,mBAAA,CAAe,UAAU,MAAM;AACpC,UAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,QAC1D,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAA,CACP,YACA,OAAA,EACG;AACH,EAAA,IACG,UAAA,CAAuE,cAAc,CAAA,IACrF,UAAA,CAAwE,eAAe,CAAA,EACxF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,MAAA,EAAQ;AAC9B,IAAA,UAAA,CAAW,QAAQ,MAAA,GAAS,IAAI,KAAA,CAAM,UAAA,CAAW,QAAQ,MAAA,EAAQ;AAAA,MAC/D,KAAA,EAAO,CAAC,cAAA,EAAgB,aAAA,EAAe,UAAA,KAAe;AACpD,QAAA,MAAM,WAAWC,kBAAA,EAAc;AAE/B,QAAA,OAAOC,qBAAgBC,8BAAA,CAAyB,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,KAAe;AACnF,UAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAIlC,UAAA,MAAM,cAAA,GAAiB,WAAW,CAAC,CAAA;AACnC,UAAA,IAAIC,kBAAa,cAAc,CAAA,IAAK,OAAO,cAAA,CAAe,SAAS,UAAA,EAAY;AAC7E,YAAA,cAAA,CAAe,OAAO,YAAA,CAAa,cAAA,CAAe,IAAA,EAAM,IAAA,EAAM,UAAU,SAAS,CAAA;AAAA,UACnF;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,eAAe,UAAU,CAAA;AAGnE,YAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,cAAA,IAAA,CAAK,GAAA,EAAI;AAAA,YACX;AAEA,YAAA,OAAO,MAAA;AAAA,UACT,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAGD,IAAAC,6BAAA,CAAyB,UAAA,EAAkD,gBAAgB,IAAI,CAAA;AAAA,EACjG;AAEA,EAAA,OAAO,UAAA;AACT;AAqBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,UAAU,CAAA,KAAM;AAC7D,IAAA,OAAO,wBAAA,CAAyB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;;;;;"}
1
+ {"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { isObjectLike, addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (isObjectLike(middlewareArgs) && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":["withActiveSpan","getActiveSpan","startSpanManual","getMiddlewareSpanOptions","isObjectLike","addNonEnumerableProperty"],"mappings":";;;;;;AAMA,MAAM,cAAA,GAAiB,oBAAA;AAChB,MAAM,eAAA,GAAkB;AAM/B,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,QAAA,EACA,SAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,KAAA,EAAO,CAAC,YAAA,EAAc,WAAA,EAAa,QAAA,KAAa;AAC9C,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,IAAA,CAAK,GAAA,EAAI;AAET,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAOA,mBAAA,CAAe,UAAU,MAAM;AACpC,UAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,QAC1D,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAA,CACP,YACA,OAAA,EACG;AACH,EAAA,IACG,UAAA,CAAuE,cAAc,CAAA,IACrF,UAAA,CAAwE,eAAe,CAAA,EACxF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,MAAA,EAAQ;AAC9B,IAAA,UAAA,CAAW,QAAQ,MAAA,GAAS,IAAI,KAAA,CAAM,UAAA,CAAW,QAAQ,MAAA,EAAQ;AAAA,MAC/D,KAAA,EAAO,CAAC,cAAA,EAAgB,aAAA,EAAe,UAAA,KAAe;AACpD,QAAA,MAAM,WAAWC,kBAAA,EAAc;AAE/B,QAAA,OAAOC,qBAAgBC,8BAAA,CAAyB,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,KAAe;AACnF,UAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAIlC,UAAA,MAAM,cAAA,GAAiB,WAAW,CAAC,CAAA;AACnC,UAAA,IAAIC,kBAAa,cAAc,CAAA,IAAK,OAAO,cAAA,CAAe,SAAS,UAAA,EAAY;AAC7E,YAAA,cAAA,CAAe,OAAO,YAAA,CAAa,cAAA,CAAe,IAAA,EAAM,IAAA,EAAM,UAAU,SAAS,CAAA;AAAA,UACnF;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,eAAe,UAAU,CAAA;AAGnE,YAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,cAAA,IAAA,CAAK,GAAA,EAAI;AAAA,YACX;AAEA,YAAA,OAAO,MAAA;AAAA,UACT,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAGD,IAAAC,6BAAA,CAAyB,UAAA,EAAY,gBAAgB,IAAI,CAAA;AAAA,EAC3D;AAEA,EAAA,OAAO,UAAA;AACT;AAqBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,UAAU,CAAA,KAAM;AAC7D,IAAA,OAAO,wBAAA,CAAyB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;;;;;"}
@@ -1,14 +1,15 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const attributes = require('@sentry/conventions/attributes');
4
+ const op = require('@sentry/conventions/op');
3
5
  const node = require('@sentry/node');
4
6
 
5
7
  function getMiddlewareSpanOptions(name) {
6
8
  return {
7
- op: "middleware.tanstackstart",
8
9
  name,
9
10
  attributes: {
10
11
  [node.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.middleware.tanstackstart",
11
- [node.SEMANTIC_ATTRIBUTE_SENTRY_OP]: "middleware.tanstackstart"
12
+ [attributes.SENTRY_OP]: op.WEB_SERVER_MIDDLEWARE_SPAN_OP
12
13
  }
13
14
  };
14
15
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["import type { StartSpanOptions } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';\n\n/**\n * Returns span options for TanStack Start middleware spans.\n */\nexport function getMiddlewareSpanOptions(name: string): StartSpanOptions {\n return {\n op: 'middleware.tanstackstart',\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.middleware.tanstackstart',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'middleware.tanstackstart',\n },\n };\n}\n"],"names":["SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP"],"mappings":";;;;AAMO,SAAS,yBAAyB,IAAA,EAAgC;AACvE,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,0BAAA;AAAA,IACJ,IAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,CAACA,qCAAgC,GAAG,+BAAA;AAAA,MACpC,CAACC,iCAA4B,GAAG;AAAA;AAClC,GACF;AACF;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["import { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { WEB_SERVER_MIDDLEWARE_SPAN_OP } from '@sentry/conventions/op';\nimport type { StartSpanOptions } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';\n\n/**\n * Returns span options for TanStack Start middleware spans.\n */\nexport function getMiddlewareSpanOptions(name: string): StartSpanOptions {\n return {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.middleware.tanstackstart',\n [SENTRY_OP]: WEB_SERVER_MIDDLEWARE_SPAN_OP,\n },\n };\n}\n"],"names":["SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_OP","WEB_SERVER_MIDDLEWARE_SPAN_OP"],"mappings":";;;;;;AAQO,SAAS,yBAAyB,IAAA,EAAgC;AACvE,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,CAACA,qCAAgC,GAAG,+BAAA;AAAA,MACpC,CAACC,oBAAS,GAAGC;AAAA;AACf,GACF;AACF;;;;"}
@@ -2,6 +2,8 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
3
  const core = require('@sentry/core');
4
4
  const node = require('@sentry/node');
5
+ const attributes = require('@sentry/conventions/attributes');
6
+ const op = require('@sentry/conventions/op');
5
7
  const routeParametrization = require('./routeParametrization.js');
6
8
 
7
9
  function addMetaTagToHead(htmlChunk, metaTagsStr) {
@@ -86,14 +88,12 @@ function wrapFetchWithSentry(serverEntry) {
86
88
  const url = new URL(request.url);
87
89
  const method = request.method || "GET";
88
90
  if (url.pathname.includes("_serverFn") || url.pathname.includes("createServerFn")) {
89
- const op = "function.tanstackstart";
90
91
  return await node.startSpan(
91
92
  {
92
- op,
93
93
  name: `${method} ${url.pathname}`,
94
94
  attributes: {
95
95
  [node.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.tanstackstart.server",
96
- [node.SEMANTIC_ATTRIBUTE_SENTRY_OP]: op
96
+ [attributes.SENTRY_OP]: op.WEB_SERVER_FUNCTION_SPAN_OP
97
97
  }
98
98
  },
99
99
  async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless, getTraceMetaTags } from '@sentry/core';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startSpan,\n} from '@sentry/node';\nimport { updateSpanWithRouteParametrization } from './routeParametrization';\n\ndeclare const __SENTRY_ROUTE_PATTERNS__: string[] | undefined;\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function optimistically assumes that the HTML coming in chunks will not be split\n * within the <head> tag. If this still happens, we simply won't replace anything.\n */\nfunction addMetaTagToHead(htmlChunk: string, metaTagsStr: string): string {\n if (typeof htmlChunk !== 'string' || !metaTagsStr) {\n return htmlChunk;\n }\n\n if (htmlChunk.includes('\"sentry-trace\"')) {\n return htmlChunk;\n }\n\n // Skip quoted attribute values so we don't match <head> inside e.g. data-code=\"...<head>...\"\n let replaced = false;\n return htmlChunk.replace(/\"[^\"]*\"|'[^']*'|(<head>)/g, (match, headTag) => {\n if (headTag && !replaced) {\n replaced = true;\n return `<head>${metaTagsStr}`;\n }\n return match;\n });\n}\n\nfunction injectMetaTagsInResponse(originalResponse: Response): Response {\n try {\n const contentType = originalResponse.headers.get('content-type');\n\n const isPageloadRequest = contentType?.startsWith('text/html');\n if (!isPageloadRequest) {\n return originalResponse;\n }\n\n // Type case necessary b/c the body's ReadableStream type doesn't include\n // the async iterator that is actually available in Node\n // We later on use the async iterator to read the body chunks\n // see https://github.com/microsoft/TypeScript/issues/39051\n const originalBody = originalResponse.body as NodeJS.ReadableStream | null;\n if (!originalBody) {\n return originalResponse;\n }\n\n const metaTagsStr = getTraceMetaTags();\n const decoder = new TextDecoder();\n\n const newResponseStream = new ReadableStream({\n start: async controller => {\n // Assign to a new variable to avoid TS losing the narrower type checked above.\n const body = originalBody;\n\n async function* bodyReporter(): AsyncGenerator<string | Buffer> {\n try {\n for await (const chunk of body) {\n yield chunk;\n }\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\n }\n\n let errored = false;\n try {\n for await (const chunk of bodyReporter()) {\n const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n const modifiedHtml = addMetaTagToHead(html, metaTagsStr);\n controller.enqueue(new TextEncoder().encode(modifiedHtml));\n }\n } catch (e) {\n errored = true;\n controller.error(e);\n } finally {\n if (!errored) {\n controller.close();\n }\n }\n },\n });\n\n return new Response(newResponseStream, {\n status: originalResponse.status,\n statusText: originalResponse.statusText,\n headers: new Headers(originalResponse.headers),\n });\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\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 op = 'function.tanstackstart';\n\n return await startSpan(\n {\n op,\n name: `${method} ${url.pathname}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n },\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n if (typeof __SENTRY_ROUTE_PATTERNS__ !== 'undefined') {\n updateSpanWithRouteParametrization(method, url.pathname, __SENTRY_ROUTE_PATTERNS__);\n }\n\n return injectMetaTagsInResponse(await target.apply(thisArg, args));\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":["getTraceMetaTags","captureException","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","updateSpanWithRouteParametrization","flushIfServerless"],"mappings":"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"}
1
+ {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless, getTraceMetaTags } from '@sentry/core';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { WEB_SERVER_FUNCTION_SPAN_OP } from '@sentry/conventions/op';\nimport { updateSpanWithRouteParametrization } from './routeParametrization';\n\ndeclare const __SENTRY_ROUTE_PATTERNS__: string[] | undefined;\n\nexport type ServerEntry = {\n // `opts` is forwarded verbatim to the wrapped handler, so this must accept whatever shape\n // the real framework entry uses (e.g. TanStack's `RequestOptions<Register>`). Under\n // parameter contravariance `unknown` would reject such an entry; `any` keeps it assignable.\n // oxlint-disable-next-line typescript/no-explicit-any\n fetch: (request: Request, opts?: any) => Promise<Response> | Response;\n};\n\n/**\n * This function optimistically assumes that the HTML coming in chunks will not be split\n * within the <head> tag. If this still happens, we simply won't replace anything.\n */\nfunction addMetaTagToHead(htmlChunk: string, metaTagsStr: string): string {\n if (typeof htmlChunk !== 'string' || !metaTagsStr) {\n return htmlChunk;\n }\n\n if (htmlChunk.includes('\"sentry-trace\"')) {\n return htmlChunk;\n }\n\n // Skip quoted attribute values so we don't match <head> inside e.g. data-code=\"...<head>...\"\n let replaced = false;\n return htmlChunk.replace(/\"[^\"]*\"|'[^']*'|(<head>)/g, (match, headTag) => {\n if (headTag && !replaced) {\n replaced = true;\n return `<head>${metaTagsStr}`;\n }\n return match;\n });\n}\n\nfunction injectMetaTagsInResponse(originalResponse: Response): Response {\n try {\n const contentType = originalResponse.headers.get('content-type');\n\n const isPageloadRequest = contentType?.startsWith('text/html');\n if (!isPageloadRequest) {\n return originalResponse;\n }\n\n // Type case necessary b/c the body's ReadableStream type doesn't include\n // the async iterator that is actually available in Node\n // We later on use the async iterator to read the body chunks\n // see https://github.com/microsoft/TypeScript/issues/39051\n const originalBody = originalResponse.body as NodeJS.ReadableStream | null;\n if (!originalBody) {\n return originalResponse;\n }\n\n const metaTagsStr = getTraceMetaTags();\n const decoder = new TextDecoder();\n\n const newResponseStream = new ReadableStream({\n start: async controller => {\n // Assign to a new variable to avoid TS losing the narrower type checked above.\n const body = originalBody;\n\n async function* bodyReporter(): AsyncGenerator<string | Buffer> {\n try {\n for await (const chunk of body) {\n yield chunk;\n }\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\n }\n\n let errored = false;\n try {\n for await (const chunk of bodyReporter()) {\n const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n const modifiedHtml = addMetaTagToHead(html, metaTagsStr);\n controller.enqueue(new TextEncoder().encode(modifiedHtml));\n }\n } catch (e) {\n errored = true;\n controller.error(e);\n } finally {\n if (!errored) {\n controller.close();\n }\n }\n },\n });\n\n return new Response(newResponseStream, {\n status: originalResponse.status,\n statusText: originalResponse.statusText,\n headers: new Headers(originalResponse.headers),\n });\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\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 return await startSpan(\n {\n name: `${method} ${url.pathname}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SENTRY_OP]: WEB_SERVER_FUNCTION_SPAN_OP,\n },\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n if (typeof __SENTRY_ROUTE_PATTERNS__ !== 'undefined') {\n updateSpanWithRouteParametrization(method, url.pathname, __SENTRY_ROUTE_PATTERNS__);\n }\n\n return injectMetaTagsInResponse(await target.apply(thisArg, args));\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":["getTraceMetaTags","captureException","startSpan","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SENTRY_OP","WEB_SERVER_FUNCTION_SPAN_OP","updateSpanWithRouteParametrization","flushIfServerless"],"mappings":"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"}
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const vite = require('@sentry/server-utils/orchestrion/vite');
3
4
  const autoInstrumentMiddleware = require('./autoInstrumentMiddleware.js');
4
5
  const routePatterns = require('./routePatterns.js');
5
6
  const sourceMaps = require('./sourceMaps.js');
@@ -13,6 +14,7 @@ function sentryTanstackStart(options = {}) {
13
14
  if (process.env.NODE_ENV === "development") {
14
15
  return plugins;
15
16
  }
17
+ plugins.push(vite.sentryOrchestrionPlugin({ buildTimeInstrumentation: options.buildTimeInstrumentation }));
16
18
  plugins.push(...sourceMaps.makeAddSentryVitePlugin(options));
17
19
  if (options.autoInstrumentMiddleware !== false) {
18
20
  plugins.push(autoInstrumentMiddleware.makeAutoInstrumentMiddlewarePlugin({ enabled: true, debug: options.debug }));
@@ -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 { makeRoutePatternPlugin } from './routePatterns';\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 * Options related to react component name annotations.\n * Disabled by default, unless a value is set for this option.\n * When enabled, your app's DOM will automatically be annotated during build-time with their respective component names.\n * This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.\n * Please note that this feature is not currently supported by the esbuild bundler plugins, and will only annotate React components\n */\n reactComponentAnnotation?: {\n /**\n * Whether the component name annotate plugin should be enabled or not.\n */\n enabled?: boolean;\n\n /**\n * A list of strings representing the names of components to ignore. The plugin will not apply `data-sentry` annotations on the DOM element for these components.\n */\n ignoredComponents?: string[];\n };\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 plugins: Plugin[] = [makeRoutePatternPlugin()];\n\n if (options.tunnelRoute) {\n plugins.push(makeTunnelRoutePlugin(options.tunnelRoute, options.debug));\n }\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return plugins;\n }\n\n plugins.push(...makeAddSentryVitePlugin(options));\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":["makeRoutePatternPlugin","makeTunnelRoutePlugin","makeAddSentryVitePlugin","makeAutoInstrumentMiddlewarePlugin","makeEnableSourceMapsVitePlugin"],"mappings":";;;;;;;AAsFO,SAAS,mBAAA,CAAoB,OAAA,GAAsC,EAAC,EAAa;AACtF,EAAA,MAAM,OAAA,GAAoB,CAACA,oCAAA,EAAwB,CAAA;AAEnD,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,OAAA,CAAQ,KAAKC,iCAAA,CAAsB,OAAA,CAAQ,WAAA,EAAa,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACxE;AAGA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAA,CAAQ,IAAA,CAAK,GAAGC,kCAAA,CAAwB,OAAO,CAAC,CAAA;AAGhD,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;;;;"}
1
+ {"version":3,"file":"sentryTanstackStart.js","sources":["../../../src/vite/sentryTanstackStart.ts"],"sourcesContent":["import type { BuildTimeOptionsBase } from '@sentry/core';\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport type { Plugin } from 'vite';\nimport { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware';\nimport { makeRoutePatternPlugin } from './routePatterns';\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 * Options related to react component name annotations.\n * Disabled by default, unless a value is set for this option.\n * When enabled, your app's DOM will automatically be annotated during build-time with their respective component names.\n * This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.\n * Please note that this feature is not currently supported by the esbuild bundler plugins, and will only annotate React components\n */\n reactComponentAnnotation?: {\n /**\n * Whether the component name annotate plugin should be enabled or not.\n */\n enabled?: boolean;\n\n /**\n * A list of strings representing the names of components to ignore. The plugin will not apply `data-sentry` annotations on the DOM element for these components.\n */\n ignoredComponents?: string[];\n };\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 plugins: Plugin[] = [makeRoutePatternPlugin()];\n\n if (options.tunnelRoute) {\n plugins.push(makeTunnelRoutePlugin(options.tunnelRoute, options.debug));\n }\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return plugins;\n }\n\n // Runs the orchestrion code transform over the server bundle so instrumented DB drivers get\n // `diagnostics_channel` publishers injected. Production-only: it force-bundles the instrumented\n // (CommonJS) deps via `ssr.noExternal`, which the `vite dev` SSR module runner can't evaluate.\n plugins.push(sentryOrchestrionPlugin({ buildTimeInstrumentation: options.buildTimeInstrumentation }));\n\n plugins.push(...makeAddSentryVitePlugin(options));\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":["makeRoutePatternPlugin","makeTunnelRoutePlugin","sentryOrchestrionPlugin","makeAddSentryVitePlugin","makeAutoInstrumentMiddlewarePlugin","makeEnableSourceMapsVitePlugin"],"mappings":";;;;;;;;AAuFO,SAAS,mBAAA,CAAoB,OAAA,GAAsC,EAAC,EAAa;AACtF,EAAA,MAAM,OAAA,GAAoB,CAACA,oCAAA,EAAwB,CAAA;AAEnD,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,OAAA,CAAQ,KAAKC,iCAAA,CAAsB,OAAA,CAAQ,WAAA,EAAa,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACxE;AAGA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,IAAA,OAAO,OAAA;AAAA,EACT;AAKA,EAAA,OAAA,CAAQ,KAAKC,4BAAA,CAAwB,EAAE,0BAA0B,OAAA,CAAQ,wBAAA,EAA0B,CAAC,CAAA;AAEpG,EAAA,OAAA,CAAQ,IAAA,CAAK,GAAGC,kCAAA,CAAwB,OAAO,CAAC,CAAA;AAGhD,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;;;;"}
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const vitePlugin = require('@sentry/vite-plugin');
3
+ const vite = require('@sentry/bundler-plugins/vite');
4
4
 
5
5
  function makeAddSentryVitePlugin(options) {
6
6
  const {
@@ -41,7 +41,7 @@ function makeAddSentryVitePlugin(options) {
41
41
  }
42
42
  }
43
43
  };
44
- const sentryPlugins = vitePlugin.sentryVitePlugin({
44
+ const sentryPlugins = vite.sentryVitePlugin({
45
45
  applicationKey,
46
46
  authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,
47
47
  bundleSizeOptimizations: bundleSizeOptimizations ?? void 0,
@@ -1 +1 @@
1
- {"version":3,"file":"sourceMaps.js","sources":["../../../src/vite/sourceMaps.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryTanstackStartOptions } from './sentryTanstackStart';\n\ntype FilesToDeleteAfterUpload = string | string[] | undefined;\n\n/**\n * A Sentry plugin for adding the @sentry/vite-plugin to automatically upload source maps to Sentry.\n */\nexport function makeAddSentryVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n const {\n applicationKey,\n authToken,\n bundleSizeOptimizations,\n debug,\n errorHandler,\n headers,\n org,\n project,\n release,\n sentryUrl,\n silent,\n sourcemaps,\n telemetry,\n reactComponentAnnotation,\n } = options;\n\n // defer resolving the filesToDeleteAfterUpload until we got access to the Vite config\n let resolveFilesToDeleteAfterUpload: ((value: FilesToDeleteAfterUpload) => void) | undefined;\n const filesToDeleteAfterUploadPromise = new Promise<FilesToDeleteAfterUpload>(resolve => {\n resolveFilesToDeleteAfterUpload = resolve;\n });\n\n const configPlugin: Plugin = {\n name: 'sentry-tanstackstart-files-to-delete-after-upload-plugin',\n apply: 'build',\n enforce: 'post',\n config(config) {\n const userFilesToDelete = sourcemaps?.filesToDeleteAfterUpload;\n\n // Only auto-delete source maps if the user didn't configure sourcemaps at all\n if (typeof userFilesToDelete === 'undefined' && typeof config.build?.sourcemap === 'undefined') {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: [\"./**/*.map\"]` to delete generated source maps after they were uploaded to Sentry.',\n );\n }\n resolveFilesToDeleteAfterUpload?.(['./**/*.map']);\n } else {\n resolveFilesToDeleteAfterUpload?.(userFilesToDelete);\n }\n },\n };\n\n const sentryPlugins = sentryVitePlugin({\n applicationKey,\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations: bundleSizeOptimizations ?? undefined,\n debug: debug ?? false,\n errorHandler,\n headers,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n release,\n silent,\n sourcemaps: {\n assets: sourcemaps?.assets,\n disable: sourcemaps?.disable,\n ignore: sourcemaps?.ignore,\n // BuildTimeOptionsBase types can lag behind bundler plugin options in some local setups.\n // Keep runtime support while staying resilient to type version skew.\n rewriteSources: (sourcemaps as unknown as { rewriteSources?: unknown } | undefined)?.rewriteSources as never,\n filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n },\n telemetry: telemetry ?? true,\n url: sentryUrl,\n _metaOptions: {\n telemetry: {\n metaFramework: 'tanstackstart-react',\n },\n },\n });\n\n return [configPlugin, ...sentryPlugins];\n}\n\n/**\n * A Sentry plugin for TanStack Start React to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n return [\n {\n name: 'sentry-tanstackstart-react-source-maps',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n },\n ];\n}\n\n/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - We won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryTanstackStartOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteUserSourceMapSetting = viteConfig.build?.sourcemap;\n const settingKey = 'vite.build.sourcemap';\n const debug = sentryPluginOptions?.debug;\n\n // Respect user source map setting if it is explicitly set\n if (viteUserSourceMapSetting === false) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.warn(\n `[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.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Source map generation is disabled in your TanStack Start configuration.');\n }\n\n return viteUserSourceMapSetting;\n } else if (viteUserSourceMapSetting && ['hidden', 'inline', true].includes(viteUserSourceMapSetting)) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteUserSourceMapSetting.toString()}\\`. Sentry will keep this source map setting.`,\n );\n }\n\n return viteUserSourceMapSetting;\n }\n\n // If the user did not specify a source map setting, we enable 'hidden' by default\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n }\n\n return 'hidden';\n}\n"],"names":["sentryVitePlugin"],"mappings":"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"}
1
+ {"version":3,"file":"sourceMaps.js","sources":["../../../src/vite/sourceMaps.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/bundler-plugins/vite';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryTanstackStartOptions } from './sentryTanstackStart';\n\ntype FilesToDeleteAfterUpload = string | string[] | undefined;\n\n/**\n * A Sentry plugin for adding the @sentry/bundler-plugins/vite to automatically upload source maps to Sentry.\n */\nexport function makeAddSentryVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n const {\n applicationKey,\n authToken,\n bundleSizeOptimizations,\n debug,\n errorHandler,\n headers,\n org,\n project,\n release,\n sentryUrl,\n silent,\n sourcemaps,\n telemetry,\n reactComponentAnnotation,\n } = options;\n\n // defer resolving the filesToDeleteAfterUpload until we got access to the Vite config\n let resolveFilesToDeleteAfterUpload: ((value: FilesToDeleteAfterUpload) => void) | undefined;\n const filesToDeleteAfterUploadPromise = new Promise<FilesToDeleteAfterUpload>(resolve => {\n resolveFilesToDeleteAfterUpload = resolve;\n });\n\n const configPlugin: Plugin = {\n name: 'sentry-tanstackstart-files-to-delete-after-upload-plugin',\n apply: 'build',\n enforce: 'post',\n config(config) {\n const userFilesToDelete = sourcemaps?.filesToDeleteAfterUpload;\n\n // Only auto-delete source maps if the user didn't configure sourcemaps at all\n if (typeof userFilesToDelete === 'undefined' && typeof config.build?.sourcemap === 'undefined') {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: [\"./**/*.map\"]` to delete generated source maps after they were uploaded to Sentry.',\n );\n }\n resolveFilesToDeleteAfterUpload?.(['./**/*.map']);\n } else {\n resolveFilesToDeleteAfterUpload?.(userFilesToDelete);\n }\n },\n };\n\n const sentryPlugins = sentryVitePlugin({\n applicationKey,\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations: bundleSizeOptimizations ?? undefined,\n debug: debug ?? false,\n errorHandler,\n headers,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n release,\n silent,\n sourcemaps: {\n assets: sourcemaps?.assets,\n disable: sourcemaps?.disable,\n ignore: sourcemaps?.ignore,\n // BuildTimeOptionsBase types can lag behind bundler plugin options in some local setups.\n // Keep runtime support while staying resilient to type version skew.\n rewriteSources: (sourcemaps as unknown as { rewriteSources?: unknown } | undefined)?.rewriteSources as never,\n filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n },\n telemetry: telemetry ?? true,\n url: sentryUrl,\n _metaOptions: {\n telemetry: {\n metaFramework: 'tanstackstart-react',\n },\n },\n });\n\n return [configPlugin, ...sentryPlugins];\n}\n\n/**\n * A Sentry plugin for TanStack Start React to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n return [\n {\n name: 'sentry-tanstackstart-react-source-maps',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n },\n ];\n}\n\n/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - We won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryTanstackStartOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteUserSourceMapSetting = viteConfig.build?.sourcemap;\n const settingKey = 'vite.build.sourcemap';\n const debug = sentryPluginOptions?.debug;\n\n // Respect user source map setting if it is explicitly set\n if (viteUserSourceMapSetting === false) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.warn(\n `[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.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Source map generation is disabled in your TanStack Start configuration.');\n }\n\n return viteUserSourceMapSetting;\n } else if (viteUserSourceMapSetting && ['hidden', 'inline', true].includes(viteUserSourceMapSetting)) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteUserSourceMapSetting.toString()}\\`. Sentry will keep this source map setting.`,\n );\n }\n\n return viteUserSourceMapSetting;\n }\n\n // If the user did not specify a source map setting, we enable 'hidden' by default\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n }\n\n return 'hidden';\n}\n"],"names":["sentryVitePlugin"],"mappings":";;;;AASO,SAAS,wBAAwB,OAAA,EAA+C;AACrF,EAAA,MAAM;AAAA,IACJ,cAAA;AAAA,IACA,SAAA;AAAA,IACA,uBAAA;AAAA,IACA,KAAA;AAAA,IACA,YAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAA;AAAA,IACA,OAAA;AAAA,IACA,OAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA;AAAA,IACA,SAAA;AAAA,IACA;AAAA,GACF,GAAI,OAAA;AAGJ,EAAA,IAAI,+BAAA;AACJ,EAAA,MAAM,+BAAA,GAAkC,IAAI,OAAA,CAAkC,CAAA,OAAA,KAAW;AACvF,IAAA,+BAAA,GAAkC,OAAA;AAAA,EACpC,CAAC,CAAA;AAED,EAAA,MAAM,YAAA,GAAuB;AAAA,IAC3B,IAAA,EAAM,0DAAA;AAAA,IACN,KAAA,EAAO,OAAA;AAAA,IACP,OAAA,EAAS,MAAA;AAAA,IACT,OAAO,MAAA,EAAQ;AACb,MAAA,MAAM,oBAAoB,UAAA,EAAY,wBAAA;AAGtC,MAAA,IAAI,OAAO,iBAAA,KAAsB,WAAA,IAAe,OAAO,MAAA,CAAO,KAAA,EAAO,cAAc,WAAA,EAAa;AAC9F,QAAA,IAAI,KAAA,EAAO;AAET,UAAA,OAAA,CAAQ,GAAA;AAAA,YACN;AAAA,WACF;AAAA,QACF;AACA,QAAA,+BAAA,GAAkC,CAAC,YAAY,CAAC,CAAA;AAAA,MAClD,CAAA,MAAO;AACL,QAAA,+BAAA,GAAkC,iBAAiB,CAAA;AAAA,MACrD;AAAA,IACF;AAAA,GACF;AAEA,EAAA,MAAM,gBAAgBA,qBAAA,CAAiB;AAAA,IACrC,cAAA;AAAA,IACA,SAAA,EAAW,SAAA,IAAa,OAAA,CAAQ,GAAA,CAAI,iBAAA;AAAA,IACpC,yBAAyB,uBAAA,IAA2B,MAAA;AAAA,IACpD,OAAO,KAAA,IAAS,KAAA;AAAA,IAChB,YAAA;AAAA,IACA,OAAA;AAAA,IACA,GAAA,EAAK,GAAA,IAAO,OAAA,CAAQ,GAAA,CAAI,UAAA;AAAA,IACxB,OAAA,EAAS,OAAA,IAAW,OAAA,CAAQ,GAAA,CAAI,cAAA;AAAA,IAChC,OAAA;AAAA,IACA,MAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,QAAQ,UAAA,EAAY,MAAA;AAAA,MACpB,SAAS,UAAA,EAAY,OAAA;AAAA,MACrB,QAAQ,UAAA,EAAY,MAAA;AAAA;AAAA;AAAA,MAGpB,gBAAiB,UAAA,EAAoE,cAAA;AAAA,MACrF,wBAAA,EAA0B;AAAA,KAC5B;AAAA,IACA,wBAAA,EAA0B;AAAA,MACxB,OAAA,EAAS,0BAA0B,OAAA,IAAW,MAAA;AAAA,MAC9C,iBAAA,EAAmB,0BAA0B,iBAAA,IAAqB;AAAA,KACpE;AAAA,IACA,WAAW,SAAA,IAAa,IAAA;AAAA,IACxB,GAAA,EAAK,SAAA;AAAA,IACL,YAAA,EAAc;AAAA,MACZ,SAAA,EAAW;AAAA,QACT,aAAA,EAAe;AAAA;AACjB;AACF,GACD,CAAA;AAED,EAAA,OAAO,CAAC,YAAA,EAAc,GAAG,aAAa,CAAA;AACxC;AAKO,SAAS,+BAA+B,OAAA,EAA+C;AAC5F,EAAA,OAAO;AAAA,IACL;AAAA,MACE,IAAA,EAAM,wCAAA;AAAA,MACN,KAAA,EAAO,OAAA;AAAA,MACP,OAAA,EAAS,MAAA;AAAA,MACT,OAAO,UAAA,EAAY;AACjB,QAAA,OAAO;AAAA,UACL,GAAG,UAAA;AAAA,UACH,KAAA,EAAO;AAAA,YACL,GAAG,UAAA,CAAW,KAAA;AAAA,YACd,SAAA,EAAW,2BAAA,CAA4B,UAAA,EAAY,OAAO;AAAA;AAC5D,SACF;AAAA,MACF;AAAA;AACF,GACF;AACF;AAiBO,SAAS,2BAAA,CACd,YACA,mBAAA,EAC+B;AAC/B,EAAA,UAAA,CAAW,KAAA,GAAQ,UAAA,CAAW,KAAA,IAAS,EAAC;AAExC,EAAA,MAAM,wBAAA,GAA2B,WAAW,KAAA,EAAO,SAAA;AACnD,EAAA,MAAM,UAAA,GAAa,sBAAA;AACnB,EAAA,MAAM,QAAQ,mBAAA,EAAqB,KAAA;AAGnC,EAAA,IAAI,6BAA6B,KAAA,EAAO;AACtC,IAAA,IAAI,KAAA,EAAO;AAET,MAAA,OAAA,CAAQ,IAAA;AAAA,QACN,gGAAgG,UAAU,CAAA,kIAAA;AAAA,OAC5G;AAAA,IACF,CAAA,MAAO;AAEL,MAAA,OAAA,CAAQ,KAAK,kFAAkF,CAAA;AAAA,IACjG;AAEA,IAAA,OAAO,wBAAA;AAAA,EACT,CAAA,MAAA,IAAW,4BAA4B,CAAC,QAAA,EAAU,UAAU,IAAI,CAAA,CAAE,QAAA,CAAS,wBAAwB,CAAA,EAAG;AACpG,IAAA,IAAI,KAAA,EAAO;AAET,MAAA,OAAA,CAAQ,GAAA;AAAA,QACN,CAAA,yBAAA,EAA4B,UAAU,CAAA,eAAA,EAAkB,wBAAA,CAAyB,UAAU,CAAA,6CAAA;AAAA,OAC7F;AAAA,IACF;AAEA,IAAA,OAAO,wBAAA;AAAA,EACT;AAGA,EAAA,IAAI,KAAA,EAAO;AAET,IAAA,OAAA,CAAQ,GAAA;AAAA,MACN,sEAAsE,UAAU,CAAA,iFAAA;AAAA,KAClF;AAAA,EACF;AAEA,EAAA,OAAO,QAAA;AACT;;;;;;"}
@@ -1 +1 @@
1
- {"type":"module","version":"10.68.0","sideEffects":false}
1
+ {"type":"module","version":"11.0.0-alpha.0","sideEffects":false}
@@ -20,7 +20,7 @@ function createSentryFunctionMiddlewareHandler(mechanismType) {
20
20
  }) {
21
21
  const activeSpan = getActiveSpan();
22
22
  const spanData = activeSpan ? spanToJSON(activeSpan) : void 0;
23
- if (activeSpan && spanData?.op === "function.tanstackstart") {
23
+ if (activeSpan && spanData?.origin === "auto.function.tanstackstart.server") {
24
24
  if (serverFnMeta?.name) {
25
25
  const method = spanData.description?.split(" ")[0] || "GET";
26
26
  updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);
@@ -1 +1 @@
1
- {"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n spanToJSON,\n updateSpanName,\n} from '@sentry/core';\nimport type { SentryGlobalFunctionMiddleware, SentryGlobalRequestMiddleware } from '../common/types';\nimport { SENTRY_INTERNAL } from './middleware';\n\ntype ServerFnMeta = {\n id?: string;\n name?: string;\n filename?: string;\n};\n\nfunction createSentryMiddlewareHandler(mechanismType: string) {\n return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\nfunction createSentryFunctionMiddlewareHandler(mechanismType: string) {\n return async function sentryFunctionMiddlewareHandler({\n next,\n serverFnMeta,\n }: {\n next: () => Promise<unknown>;\n serverFnMeta?: ServerFnMeta;\n }): Promise<unknown> {\n const activeSpan = getActiveSpan();\n const spanData = activeSpan ? spanToJSON(activeSpan) : undefined;\n if (activeSpan && spanData?.op === 'function.tanstackstart') {\n if (serverFnMeta?.name) {\n const method = spanData.description?.split(' ')[0] || 'GET';\n updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n if (serverFnMeta?.id) {\n activeSpan.setAttribute('tanstackstart.function.id', serverFnMeta.id);\n }\n if (serverFnMeta?.filename) {\n activeSpan.setAttribute('tanstackstart.function.filename', serverFnMeta.filename);\n }\n }\n\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\n/**\n * Global request middleware that captures errors from API route requests.\n * Should be added as the first entry in the `requestMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n\n options: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,\n },\n};\n\n/**\n * Global function middleware that captures errors from server function invocations.\n * Should be added as the first entry in the `functionMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n\n options: {\n server: createSentryFunctionMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (\n ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n ) => any, // eslint-disable-line @typescript-eslint/no-explicit-any\n },\n};\n\n// Mark as internal so the Vite auto-instrumentation plugin skips these middleware\naddNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);\naddNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);\n"],"names":[],"mappings":";;;AAiBA,SAAS,8BAA8B,aAAA,EAAuB;AAC5D,EAAA,OAAO,eAAe,uBAAA,CAAwB,EAAE,IAAA,EAAK,EAAuD;AAC1G,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAEA,SAAS,sCAAsC,aAAA,EAAuB;AACpE,EAAA,OAAO,eAAe,+BAAA,CAAgC;AAAA,IACpD,IAAA;AAAA,IACA;AAAA,GACF,EAGqB;AACnB,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,UAAA,CAAW,UAAU,CAAA,GAAI,MAAA;AACvD,IAAA,IAAI,UAAA,IAAc,QAAA,EAAU,EAAA,KAAO,wBAAA,EAA0B;AAC3D,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,SAAS,QAAA,CAAS,WAAA,EAAa,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,KAAA;AACtD,QAAA,cAAA,CAAe,YAAY,CAAA,EAAG,MAAM,CAAA,YAAA,EAAe,YAAA,CAAa,IAAI,CAAA,CAAE,CAAA;AACtE,QAAA,UAAA,CAAW,YAAA,CAAa,kCAAkC,OAAO,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,UAAA,CAAW,YAAA,CAAa,2BAAA,EAA6B,YAAA,CAAa,EAAE,CAAA;AAAA,MACtE;AACA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,UAAA,CAAW,YAAA,CAAa,iCAAA,EAAmC,YAAA,CAAa,QAAQ,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMO,MAAM,6BAAA,GAA+D;AAAA;AAAA,EAE1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA;AAAA,IAEP,MAAA,EAAQ,8BAA8B,uCAAuC;AAAA;AAEjF;AAMO,MAAM,8BAAA,GAAiE;AAAA;AAAA,EAE5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,sCAAsC,+CAA+C;AAAA;AAAA;AAIjG;AAGA,wBAAA,CAAyB,6BAAA,EAA+B,iBAAiB,IAAI,CAAA;AAC7E,wBAAA,CAAyB,8BAAA,EAAgC,iBAAiB,IAAI,CAAA;;;;"}
1
+ {"version":3,"file":"globalMiddleware.js","sources":["../../../src/server/globalMiddleware.ts"],"sourcesContent":["import {\n SEMANTIC_ATTRIBUTE_SENTRY_SOURCE,\n addNonEnumerableProperty,\n captureException,\n getActiveSpan,\n spanToJSON,\n updateSpanName,\n} from '@sentry/core';\nimport type { SentryGlobalFunctionMiddleware, SentryGlobalRequestMiddleware } from '../common/types';\nimport { SENTRY_INTERNAL } from './middleware';\n\ntype ServerFnMeta = {\n id?: string;\n name?: string;\n filename?: string;\n};\n\nfunction createSentryMiddlewareHandler(mechanismType: string) {\n return async function sentryMiddlewareHandler({ next }: { next: () => Promise<unknown> }): Promise<unknown> {\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\nfunction createSentryFunctionMiddlewareHandler(mechanismType: string) {\n return async function sentryFunctionMiddlewareHandler({\n next,\n serverFnMeta,\n }: {\n next: () => Promise<unknown>;\n serverFnMeta?: ServerFnMeta;\n }): Promise<unknown> {\n const activeSpan = getActiveSpan();\n const spanData = activeSpan ? spanToJSON(activeSpan) : undefined;\n if (activeSpan && spanData?.origin === 'auto.function.tanstackstart.server') {\n if (serverFnMeta?.name) {\n const method = spanData.description?.split(' ')[0] || 'GET';\n updateSpanName(activeSpan, `${method} /_serverFn/${serverFnMeta.name}`);\n activeSpan.setAttribute(SEMANTIC_ATTRIBUTE_SENTRY_SOURCE, 'route');\n }\n if (serverFnMeta?.id) {\n activeSpan.setAttribute('tanstackstart.function.id', serverFnMeta.id);\n }\n if (serverFnMeta?.filename) {\n activeSpan.setAttribute('tanstackstart.function.filename', serverFnMeta.filename);\n }\n }\n\n try {\n return await next();\n } catch (e) {\n captureException(e, {\n mechanism: { type: mechanismType, handled: false },\n });\n throw e;\n }\n };\n}\n\n/**\n * Global request middleware that captures errors from API route requests.\n * Should be added as the first entry in the `requestMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalRequestMiddleware: SentryGlobalRequestMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalRequestMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalRequestMiddleware['_types'],\n\n options: {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n server: createSentryMiddlewareHandler('auto.middleware.tanstackstart.request') as (...args: any[]) => any,\n },\n};\n\n/**\n * Global function middleware that captures errors from server function invocations.\n * Should be added as the first entry in the `functionMiddleware` array of `createStart()`.\n */\nexport const sentryGlobalFunctionMiddleware: SentryGlobalFunctionMiddleware = {\n // `~types`/`_types` only exist on the type level in TanStack Start middlewares and hold no runtime value\n '~types': undefined as unknown as SentryGlobalFunctionMiddleware['~types'],\n _types: undefined as unknown as SentryGlobalFunctionMiddleware['_types'],\n\n options: {\n server: createSentryFunctionMiddlewareHandler('auto.middleware.tanstackstart.server_function') as (\n ...args: any[] // eslint-disable-line @typescript-eslint/no-explicit-any\n ) => any, // eslint-disable-line @typescript-eslint/no-explicit-any\n },\n};\n\n// Mark as internal so the Vite auto-instrumentation plugin skips these middleware\naddNonEnumerableProperty(sentryGlobalRequestMiddleware, SENTRY_INTERNAL, true);\naddNonEnumerableProperty(sentryGlobalFunctionMiddleware, SENTRY_INTERNAL, true);\n"],"names":[],"mappings":";;;AAiBA,SAAS,8BAA8B,aAAA,EAAuB;AAC5D,EAAA,OAAO,eAAe,uBAAA,CAAwB,EAAE,IAAA,EAAK,EAAuD;AAC1G,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAEA,SAAS,sCAAsC,aAAA,EAAuB;AACpE,EAAA,OAAO,eAAe,+BAAA,CAAgC;AAAA,IACpD,IAAA;AAAA,IACA;AAAA,GACF,EAGqB;AACnB,IAAA,MAAM,aAAa,aAAA,EAAc;AACjC,IAAA,MAAM,QAAA,GAAW,UAAA,GAAa,UAAA,CAAW,UAAU,CAAA,GAAI,MAAA;AACvD,IAAA,IAAI,UAAA,IAAc,QAAA,EAAU,MAAA,KAAW,oCAAA,EAAsC;AAC3E,MAAA,IAAI,cAAc,IAAA,EAAM;AACtB,QAAA,MAAM,SAAS,QAAA,CAAS,WAAA,EAAa,MAAM,GAAG,CAAA,CAAE,CAAC,CAAA,IAAK,KAAA;AACtD,QAAA,cAAA,CAAe,YAAY,CAAA,EAAG,MAAM,CAAA,YAAA,EAAe,YAAA,CAAa,IAAI,CAAA,CAAE,CAAA;AACtE,QAAA,UAAA,CAAW,YAAA,CAAa,kCAAkC,OAAO,CAAA;AAAA,MACnE;AACA,MAAA,IAAI,cAAc,EAAA,EAAI;AACpB,QAAA,UAAA,CAAW,YAAA,CAAa,2BAAA,EAA6B,YAAA,CAAa,EAAE,CAAA;AAAA,MACtE;AACA,MAAA,IAAI,cAAc,QAAA,EAAU;AAC1B,QAAA,UAAA,CAAW,YAAA,CAAa,iCAAA,EAAmC,YAAA,CAAa,QAAQ,CAAA;AAAA,MAClF;AAAA,IACF;AAEA,IAAA,IAAI;AACF,MAAA,OAAO,MAAM,IAAA,EAAK;AAAA,IACpB,SAAS,CAAA,EAAG;AACV,MAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,QAClB,SAAA,EAAW,EAAE,IAAA,EAAM,aAAA,EAAe,SAAS,KAAA;AAAM,OAClD,CAAA;AACD,MAAA,MAAM,CAAA;AAAA,IACR;AAAA,EACF,CAAA;AACF;AAMO,MAAM,6BAAA,GAA+D;AAAA;AAAA,EAE1E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA;AAAA,IAEP,MAAA,EAAQ,8BAA8B,uCAAuC;AAAA;AAEjF;AAMO,MAAM,8BAAA,GAAiE;AAAA;AAAA,EAE5E,QAAA,EAAU,MAAA;AAAA,EACV,MAAA,EAAQ,MAAA;AAAA,EAER,OAAA,EAAS;AAAA,IACP,MAAA,EAAQ,sCAAsC,+CAA+C;AAAA;AAAA;AAIjG;AAGA,wBAAA,CAAyB,6BAAA,EAA+B,iBAAiB,IAAI,CAAA;AAC7E,wBAAA,CAAyB,8BAAA,EAAgC,iBAAiB,IAAI,CAAA;;;;"}
@@ -1 +1 @@
1
- {"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { isObjectLike, addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (isObjectLike(middlewareArgs) && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware as unknown as Record<string, unknown>, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,cAAA,GAAiB,oBAAA;AAChB,MAAM,eAAA,GAAkB;AAM/B,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,QAAA,EACA,SAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,KAAA,EAAO,CAAC,YAAA,EAAc,WAAA,EAAa,QAAA,KAAa;AAC9C,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,IAAA,CAAK,GAAA,EAAI;AAET,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,cAAA,CAAe,UAAU,MAAM;AACpC,UAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,QAC1D,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAA,CACP,YACA,OAAA,EACG;AACH,EAAA,IACG,UAAA,CAAuE,cAAc,CAAA,IACrF,UAAA,CAAwE,eAAe,CAAA,EACxF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,MAAA,EAAQ;AAC9B,IAAA,UAAA,CAAW,QAAQ,MAAA,GAAS,IAAI,KAAA,CAAM,UAAA,CAAW,QAAQ,MAAA,EAAQ;AAAA,MAC/D,KAAA,EAAO,CAAC,cAAA,EAAgB,aAAA,EAAe,UAAA,KAAe;AACpD,QAAA,MAAM,WAAW,aAAA,EAAc;AAE/B,QAAA,OAAO,gBAAgB,wBAAA,CAAyB,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,KAAe;AACnF,UAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAIlC,UAAA,MAAM,cAAA,GAAiB,WAAW,CAAC,CAAA;AACnC,UAAA,IAAI,aAAa,cAAc,CAAA,IAAK,OAAO,cAAA,CAAe,SAAS,UAAA,EAAY;AAC7E,YAAA,cAAA,CAAe,OAAO,YAAA,CAAa,cAAA,CAAe,IAAA,EAAM,IAAA,EAAM,UAAU,SAAS,CAAA;AAAA,UACnF;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,eAAe,UAAU,CAAA;AAGnE,YAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,cAAA,IAAA,CAAK,GAAA,EAAI;AAAA,YACX;AAEA,YAAA,OAAO,MAAA;AAAA,UACT,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAGD,IAAA,wBAAA,CAAyB,UAAA,EAAkD,gBAAgB,IAAI,CAAA;AAAA,EACjG;AAEA,EAAA,OAAO,UAAA;AACT;AAqBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,UAAU,CAAA,KAAM;AAC7D,IAAA,OAAO,wBAAA,CAAyB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;;;;"}
1
+ {"version":3,"file":"middleware.js","sources":["../../../src/server/middleware.ts"],"sourcesContent":["import { isObjectLike, addNonEnumerableProperty } from '@sentry/core';\nimport type { Span } from '@sentry/node';\nimport { getActiveSpan, startSpanManual, withActiveSpan } from '@sentry/node';\nimport type { MiddlewareWrapperOptions, TanStackMiddlewareBase } from '../common/types';\nimport { getMiddlewareSpanOptions } from './utils';\n\nconst SENTRY_WRAPPED = '__SENTRY_WRAPPED__';\nexport const SENTRY_INTERNAL = '__SENTRY_INTERNAL__';\n\n/**\n * Creates a proxy for the next function that ends the current span and restores the parent span.\n * This ensures that subsequent middleware spans are children of the root span, not nested children.\n */\nfunction getNextProxy<T extends (...args: unknown[]) => unknown>(\n next: T,\n span: Span,\n prevSpan: Span | undefined,\n nextState: { called: boolean },\n): T {\n return new Proxy(next, {\n apply: (originalNext, thisArgNext, argsNext) => {\n nextState.called = true;\n span.end();\n\n if (prevSpan) {\n return withActiveSpan(prevSpan, () => {\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n });\n }\n\n return Reflect.apply(originalNext, thisArgNext, argsNext);\n },\n });\n}\n\n/**\n * Wraps a TanStack Start middleware with Sentry instrumentation to create spans.\n */\nfunction wrapMiddlewareWithSentry<T extends TanStackMiddlewareBase>(\n middleware: T,\n options: MiddlewareWrapperOptions,\n): T {\n if (\n (middleware as TanStackMiddlewareBase & { [SENTRY_WRAPPED]?: boolean })[SENTRY_WRAPPED] ||\n (middleware as TanStackMiddlewareBase & { [SENTRY_INTERNAL]?: boolean })[SENTRY_INTERNAL]\n ) {\n // already instrumented or internal Sentry middleware\n return middleware;\n }\n\n // instrument server middleware\n if (middleware.options?.server) {\n middleware.options.server = new Proxy(middleware.options.server, {\n apply: (originalServer, thisArgServer, argsServer) => {\n const prevSpan = getActiveSpan();\n\n return startSpanManual(getMiddlewareSpanOptions(options.name), async (span: Span) => {\n const nextState = { called: false };\n\n // The server function receives { next, context, request } as first argument\n // Users call next() inside their middleware to move down the middleware chain. We proxy next() to end the span when it is called.\n const middlewareArgs = argsServer[0] as { next?: (...args: unknown[]) => unknown } | undefined;\n if (isObjectLike(middlewareArgs) && typeof middlewareArgs.next === 'function') {\n middlewareArgs.next = getNextProxy(middlewareArgs.next, span, prevSpan, nextState);\n }\n\n try {\n const result = await originalServer.apply(thisArgServer, argsServer);\n\n // End span here if next() wasn't called, else we already ended it in next()\n if (!nextState.called) {\n span.end();\n }\n\n return result;\n } catch (e) {\n span.end();\n throw e;\n }\n });\n },\n });\n\n // mark as instrumented\n addNonEnumerableProperty(middleware, SENTRY_WRAPPED, true);\n }\n\n return middleware;\n}\n\n/**\n * Wraps multiple TanStack Start middlewares with Sentry instrumentation.\n * Object keys are used as span names to avoid users having to specify this manually.\n *\n * @example\n * ```ts\n * import { wrapMiddlewaresWithSentry } from '@sentry/tanstackstart-react';\n *\n * const wrappedMiddlewares = wrapMiddlewaresWithSentry({\n * authMiddleware,\n * loggingMiddleware,\n * });\n *\n * createServerFn().middleware(wrappedMiddlewares)\n * ```\n *\n * @param middlewares - An object containing middlewares\n * @returns An array of wrapped middlewares\n */\nexport function wrapMiddlewaresWithSentry<T extends TanStackMiddlewareBase>(middlewares: Record<string, T>): T[] {\n return Object.entries(middlewares).map(([name, middleware]) => {\n return wrapMiddlewareWithSentry(middleware, { name });\n });\n}\n"],"names":[],"mappings":";;;;AAMA,MAAM,cAAA,GAAiB,oBAAA;AAChB,MAAM,eAAA,GAAkB;AAM/B,SAAS,YAAA,CACP,IAAA,EACA,IAAA,EACA,QAAA,EACA,SAAA,EACG;AACH,EAAA,OAAO,IAAI,MAAM,IAAA,EAAM;AAAA,IACrB,KAAA,EAAO,CAAC,YAAA,EAAc,WAAA,EAAa,QAAA,KAAa;AAC9C,MAAA,SAAA,CAAU,MAAA,GAAS,IAAA;AACnB,MAAA,IAAA,CAAK,GAAA,EAAI;AAET,MAAA,IAAI,QAAA,EAAU;AACZ,QAAA,OAAO,cAAA,CAAe,UAAU,MAAM;AACpC,UAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,QAC1D,CAAC,CAAA;AAAA,MACH;AAEA,MAAA,OAAO,OAAA,CAAQ,KAAA,CAAM,YAAA,EAAc,WAAA,EAAa,QAAQ,CAAA;AAAA,IAC1D;AAAA,GACD,CAAA;AACH;AAKA,SAAS,wBAAA,CACP,YACA,OAAA,EACG;AACH,EAAA,IACG,UAAA,CAAuE,cAAc,CAAA,IACrF,UAAA,CAAwE,eAAe,CAAA,EACxF;AAEA,IAAA,OAAO,UAAA;AAAA,EACT;AAGA,EAAA,IAAI,UAAA,CAAW,SAAS,MAAA,EAAQ;AAC9B,IAAA,UAAA,CAAW,QAAQ,MAAA,GAAS,IAAI,KAAA,CAAM,UAAA,CAAW,QAAQ,MAAA,EAAQ;AAAA,MAC/D,KAAA,EAAO,CAAC,cAAA,EAAgB,aAAA,EAAe,UAAA,KAAe;AACpD,QAAA,MAAM,WAAW,aAAA,EAAc;AAE/B,QAAA,OAAO,gBAAgB,wBAAA,CAAyB,OAAA,CAAQ,IAAI,CAAA,EAAG,OAAO,IAAA,KAAe;AACnF,UAAA,MAAM,SAAA,GAAY,EAAE,MAAA,EAAQ,KAAA,EAAM;AAIlC,UAAA,MAAM,cAAA,GAAiB,WAAW,CAAC,CAAA;AACnC,UAAA,IAAI,aAAa,cAAc,CAAA,IAAK,OAAO,cAAA,CAAe,SAAS,UAAA,EAAY;AAC7E,YAAA,cAAA,CAAe,OAAO,YAAA,CAAa,cAAA,CAAe,IAAA,EAAM,IAAA,EAAM,UAAU,SAAS,CAAA;AAAA,UACnF;AAEA,UAAA,IAAI;AACF,YAAA,MAAM,MAAA,GAAS,MAAM,cAAA,CAAe,KAAA,CAAM,eAAe,UAAU,CAAA;AAGnE,YAAA,IAAI,CAAC,UAAU,MAAA,EAAQ;AACrB,cAAA,IAAA,CAAK,GAAA,EAAI;AAAA,YACX;AAEA,YAAA,OAAO,MAAA;AAAA,UACT,SAAS,CAAA,EAAG;AACV,YAAA,IAAA,CAAK,GAAA,EAAI;AACT,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF,CAAC,CAAA;AAAA,MACH;AAAA,KACD,CAAA;AAGD,IAAA,wBAAA,CAAyB,UAAA,EAAY,gBAAgB,IAAI,CAAA;AAAA,EAC3D;AAEA,EAAA,OAAO,UAAA;AACT;AAqBO,SAAS,0BAA4D,WAAA,EAAqC;AAC/G,EAAA,OAAO,MAAA,CAAO,QAAQ,WAAW,CAAA,CAAE,IAAI,CAAC,CAAC,IAAA,EAAM,UAAU,CAAA,KAAM;AAC7D,IAAA,OAAO,wBAAA,CAAyB,UAAA,EAAY,EAAE,IAAA,EAAM,CAAA;AAAA,EACtD,CAAC,CAAA;AACH;;;;"}
@@ -1,12 +1,13 @@
1
- import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';
1
+ import { SENTRY_OP } from '@sentry/conventions/attributes';
2
+ import { WEB_SERVER_MIDDLEWARE_SPAN_OP } from '@sentry/conventions/op';
3
+ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';
2
4
 
3
5
  function getMiddlewareSpanOptions(name) {
4
6
  return {
5
- op: "middleware.tanstackstart",
6
7
  name,
7
8
  attributes: {
8
9
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.middleware.tanstackstart",
9
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: "middleware.tanstackstart"
10
+ [SENTRY_OP]: WEB_SERVER_MIDDLEWARE_SPAN_OP
10
11
  }
11
12
  };
12
13
  }
@@ -1 +1 @@
1
- {"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["import type { StartSpanOptions } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';\n\n/**\n * Returns span options for TanStack Start middleware spans.\n */\nexport function getMiddlewareSpanOptions(name: string): StartSpanOptions {\n return {\n op: 'middleware.tanstackstart',\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.middleware.tanstackstart',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: 'middleware.tanstackstart',\n },\n };\n}\n"],"names":[],"mappings":";;AAMO,SAAS,yBAAyB,IAAA,EAAgC;AACvE,EAAA,OAAO;AAAA,IACL,EAAA,EAAI,0BAAA;AAAA,IACJ,IAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,CAAC,gCAAgC,GAAG,+BAAA;AAAA,MACpC,CAAC,4BAA4B,GAAG;AAAA;AAClC,GACF;AACF;;;;"}
1
+ {"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["import { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { WEB_SERVER_MIDDLEWARE_SPAN_OP } from '@sentry/conventions/op';\nimport type { StartSpanOptions } from '@sentry/core';\nimport { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';\n\n/**\n * Returns span options for TanStack Start middleware spans.\n */\nexport function getMiddlewareSpanOptions(name: string): StartSpanOptions {\n return {\n name,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.middleware.tanstackstart',\n [SENTRY_OP]: WEB_SERVER_MIDDLEWARE_SPAN_OP,\n },\n };\n}\n"],"names":[],"mappings":";;;;AAQO,SAAS,yBAAyB,IAAA,EAAgC;AACvE,EAAA,OAAO;AAAA,IACL,IAAA;AAAA,IACA,UAAA,EAAY;AAAA,MACV,CAAC,gCAAgC,GAAG,+BAAA;AAAA,MACpC,CAAC,SAAS,GAAG;AAAA;AACf,GACF;AACF;;;;"}
@@ -1,5 +1,7 @@
1
1
  import { flushIfServerless, getTraceMetaTags } from '@sentry/core';
2
- import { startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, captureException } from '@sentry/node';
2
+ import { startSpan, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, captureException } from '@sentry/node';
3
+ import { SENTRY_OP } from '@sentry/conventions/attributes';
4
+ import { WEB_SERVER_FUNCTION_SPAN_OP } from '@sentry/conventions/op';
3
5
  import { updateSpanWithRouteParametrization } from './routeParametrization.js';
4
6
 
5
7
  function addMetaTagToHead(htmlChunk, metaTagsStr) {
@@ -84,14 +86,12 @@ function wrapFetchWithSentry(serverEntry) {
84
86
  const url = new URL(request.url);
85
87
  const method = request.method || "GET";
86
88
  if (url.pathname.includes("_serverFn") || url.pathname.includes("createServerFn")) {
87
- const op = "function.tanstackstart";
88
89
  return await startSpan(
89
90
  {
90
- op,
91
91
  name: `${method} ${url.pathname}`,
92
92
  attributes: {
93
93
  [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: "auto.function.tanstackstart.server",
94
- [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op
94
+ [SENTRY_OP]: WEB_SERVER_FUNCTION_SPAN_OP
95
95
  }
96
96
  },
97
97
  async () => {
@@ -1 +1 @@
1
- {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless, getTraceMetaTags } from '@sentry/core';\nimport {\n captureException,\n SEMANTIC_ATTRIBUTE_SENTRY_OP,\n SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN,\n startSpan,\n} from '@sentry/node';\nimport { updateSpanWithRouteParametrization } from './routeParametrization';\n\ndeclare const __SENTRY_ROUTE_PATTERNS__: string[] | undefined;\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function optimistically assumes that the HTML coming in chunks will not be split\n * within the <head> tag. If this still happens, we simply won't replace anything.\n */\nfunction addMetaTagToHead(htmlChunk: string, metaTagsStr: string): string {\n if (typeof htmlChunk !== 'string' || !metaTagsStr) {\n return htmlChunk;\n }\n\n if (htmlChunk.includes('\"sentry-trace\"')) {\n return htmlChunk;\n }\n\n // Skip quoted attribute values so we don't match <head> inside e.g. data-code=\"...<head>...\"\n let replaced = false;\n return htmlChunk.replace(/\"[^\"]*\"|'[^']*'|(<head>)/g, (match, headTag) => {\n if (headTag && !replaced) {\n replaced = true;\n return `<head>${metaTagsStr}`;\n }\n return match;\n });\n}\n\nfunction injectMetaTagsInResponse(originalResponse: Response): Response {\n try {\n const contentType = originalResponse.headers.get('content-type');\n\n const isPageloadRequest = contentType?.startsWith('text/html');\n if (!isPageloadRequest) {\n return originalResponse;\n }\n\n // Type case necessary b/c the body's ReadableStream type doesn't include\n // the async iterator that is actually available in Node\n // We later on use the async iterator to read the body chunks\n // see https://github.com/microsoft/TypeScript/issues/39051\n const originalBody = originalResponse.body as NodeJS.ReadableStream | null;\n if (!originalBody) {\n return originalResponse;\n }\n\n const metaTagsStr = getTraceMetaTags();\n const decoder = new TextDecoder();\n\n const newResponseStream = new ReadableStream({\n start: async controller => {\n // Assign to a new variable to avoid TS losing the narrower type checked above.\n const body = originalBody;\n\n async function* bodyReporter(): AsyncGenerator<string | Buffer> {\n try {\n for await (const chunk of body) {\n yield chunk;\n }\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\n }\n\n let errored = false;\n try {\n for await (const chunk of bodyReporter()) {\n const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n const modifiedHtml = addMetaTagToHead(html, metaTagsStr);\n controller.enqueue(new TextEncoder().encode(modifiedHtml));\n }\n } catch (e) {\n errored = true;\n controller.error(e);\n } finally {\n if (!errored) {\n controller.close();\n }\n }\n },\n });\n\n return new Response(newResponseStream, {\n status: originalResponse.status,\n statusText: originalResponse.statusText,\n headers: new Headers(originalResponse.headers),\n });\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\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 op = 'function.tanstackstart';\n\n return await startSpan(\n {\n op,\n name: `${method} ${url.pathname}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n },\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n if (typeof __SENTRY_ROUTE_PATTERNS__ !== 'undefined') {\n updateSpanWithRouteParametrization(method, url.pathname, __SENTRY_ROUTE_PATTERNS__);\n }\n\n return injectMetaTagsInResponse(await target.apply(thisArg, args));\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { flushIfServerless, getTraceMetaTags } from '@sentry/core';\nimport { captureException, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { SENTRY_OP } from '@sentry/conventions/attributes';\nimport { WEB_SERVER_FUNCTION_SPAN_OP } from '@sentry/conventions/op';\nimport { updateSpanWithRouteParametrization } from './routeParametrization';\n\ndeclare const __SENTRY_ROUTE_PATTERNS__: string[] | undefined;\n\nexport type ServerEntry = {\n // `opts` is forwarded verbatim to the wrapped handler, so this must accept whatever shape\n // the real framework entry uses (e.g. TanStack's `RequestOptions<Register>`). Under\n // parameter contravariance `unknown` would reject such an entry; `any` keeps it assignable.\n // oxlint-disable-next-line typescript/no-explicit-any\n fetch: (request: Request, opts?: any) => Promise<Response> | Response;\n};\n\n/**\n * This function optimistically assumes that the HTML coming in chunks will not be split\n * within the <head> tag. If this still happens, we simply won't replace anything.\n */\nfunction addMetaTagToHead(htmlChunk: string, metaTagsStr: string): string {\n if (typeof htmlChunk !== 'string' || !metaTagsStr) {\n return htmlChunk;\n }\n\n if (htmlChunk.includes('\"sentry-trace\"')) {\n return htmlChunk;\n }\n\n // Skip quoted attribute values so we don't match <head> inside e.g. data-code=\"...<head>...\"\n let replaced = false;\n return htmlChunk.replace(/\"[^\"]*\"|'[^']*'|(<head>)/g, (match, headTag) => {\n if (headTag && !replaced) {\n replaced = true;\n return `<head>${metaTagsStr}`;\n }\n return match;\n });\n}\n\nfunction injectMetaTagsInResponse(originalResponse: Response): Response {\n try {\n const contentType = originalResponse.headers.get('content-type');\n\n const isPageloadRequest = contentType?.startsWith('text/html');\n if (!isPageloadRequest) {\n return originalResponse;\n }\n\n // Type case necessary b/c the body's ReadableStream type doesn't include\n // the async iterator that is actually available in Node\n // We later on use the async iterator to read the body chunks\n // see https://github.com/microsoft/TypeScript/issues/39051\n const originalBody = originalResponse.body as NodeJS.ReadableStream | null;\n if (!originalBody) {\n return originalResponse;\n }\n\n const metaTagsStr = getTraceMetaTags();\n const decoder = new TextDecoder();\n\n const newResponseStream = new ReadableStream({\n start: async controller => {\n // Assign to a new variable to avoid TS losing the narrower type checked above.\n const body = originalBody;\n\n async function* bodyReporter(): AsyncGenerator<string | Buffer> {\n try {\n for await (const chunk of body) {\n yield chunk;\n }\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\n }\n\n let errored = false;\n try {\n for await (const chunk of bodyReporter()) {\n const html = typeof chunk === 'string' ? chunk : decoder.decode(chunk, { stream: true });\n const modifiedHtml = addMetaTagToHead(html, metaTagsStr);\n controller.enqueue(new TextEncoder().encode(modifiedHtml));\n }\n } catch (e) {\n errored = true;\n controller.error(e);\n } finally {\n if (!errored) {\n controller.close();\n }\n }\n },\n });\n\n return new Response(newResponseStream, {\n status: originalResponse.status,\n statusText: originalResponse.statusText,\n headers: new Headers(originalResponse.headers),\n });\n } catch (e) {\n captureException(e, {\n mechanism: { type: 'auto.http.tanstackstart', handled: false },\n });\n throw e;\n }\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 return await startSpan(\n {\n name: `${method} ${url.pathname}`,\n attributes: {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SENTRY_OP]: WEB_SERVER_FUNCTION_SPAN_OP,\n },\n },\n async () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n if (typeof __SENTRY_ROUTE_PATTERNS__ !== 'undefined') {\n updateSpanWithRouteParametrization(method, url.pathname, __SENTRY_ROUTE_PATTERNS__);\n }\n\n return injectMetaTagsInResponse(await target.apply(thisArg, args));\n } finally {\n await flushIfServerless();\n }\n },\n });\n }\n return serverEntry;\n}\n"],"names":[],"mappings":";;;;;;AAoBA,SAAS,gBAAA,CAAiB,WAAmB,WAAA,EAA6B;AACxE,EAAA,IAAI,OAAO,SAAA,KAAc,QAAA,IAAY,CAAC,WAAA,EAAa;AACjD,IAAA,OAAO,SAAA;AAAA,EACT;AAEA,EAAA,IAAI,SAAA,CAAU,QAAA,CAAS,gBAAgB,CAAA,EAAG;AACxC,IAAA,OAAO,SAAA;AAAA,EACT;AAGA,EAAA,IAAI,QAAA,GAAW,KAAA;AACf,EAAA,OAAO,SAAA,CAAU,OAAA,CAAQ,2BAAA,EAA6B,CAAC,OAAO,OAAA,KAAY;AACxE,IAAA,IAAI,OAAA,IAAW,CAAC,QAAA,EAAU;AACxB,MAAA,QAAA,GAAW,IAAA;AACX,MAAA,OAAO,SAAS,WAAW,CAAA,CAAA;AAAA,IAC7B;AACA,IAAA,OAAO,KAAA;AAAA,EACT,CAAC,CAAA;AACH;AAEA,SAAS,yBAAyB,gBAAA,EAAsC;AACtE,EAAA,IAAI;AACF,IAAA,MAAM,WAAA,GAAc,gBAAA,CAAiB,OAAA,CAAQ,GAAA,CAAI,cAAc,CAAA;AAE/D,IAAA,MAAM,iBAAA,GAAoB,WAAA,EAAa,UAAA,CAAW,WAAW,CAAA;AAC7D,IAAA,IAAI,CAAC,iBAAA,EAAmB;AACtB,MAAA,OAAO,gBAAA;AAAA,IACT;AAMA,IAAA,MAAM,eAAe,gBAAA,CAAiB,IAAA;AACtC,IAAA,IAAI,CAAC,YAAA,EAAc;AACjB,MAAA,OAAO,gBAAA;AAAA,IACT;AAEA,IAAA,MAAM,cAAc,gBAAA,EAAiB;AACrC,IAAA,MAAM,OAAA,GAAU,IAAI,WAAA,EAAY;AAEhC,IAAA,MAAM,iBAAA,GAAoB,IAAI,cAAA,CAAe;AAAA,MAC3C,KAAA,EAAO,OAAM,UAAA,KAAc;AAEzB,QAAA,MAAM,IAAA,GAAO,YAAA;AAEb,QAAA,gBAAgB,YAAA,GAAgD;AAC9D,UAAA,IAAI;AACF,YAAA,WAAA,MAAiB,SAAS,IAAA,EAAM;AAC9B,cAAA,MAAM,KAAA;AAAA,YACR;AAAA,UACF,SAAS,CAAA,EAAG;AACV,YAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,cAClB,SAAA,EAAW,EAAE,IAAA,EAAM,yBAAA,EAA2B,SAAS,KAAA;AAAM,aAC9D,CAAA;AACD,YAAA,MAAM,CAAA;AAAA,UACR;AAAA,QACF;AAEA,QAAA,IAAI,OAAA,GAAU,KAAA;AACd,QAAA,IAAI;AACF,UAAA,WAAA,MAAiB,KAAA,IAAS,cAAa,EAAG;AACxC,YAAA,MAAM,IAAA,GAAO,OAAO,KAAA,KAAU,QAAA,GAAW,KAAA,GAAQ,OAAA,CAAQ,MAAA,CAAO,KAAA,EAAO,EAAE,MAAA,EAAQ,IAAA,EAAM,CAAA;AACvF,YAAA,MAAM,YAAA,GAAe,gBAAA,CAAiB,IAAA,EAAM,WAAW,CAAA;AACvD,YAAA,UAAA,CAAW,QAAQ,IAAI,WAAA,EAAY,CAAE,MAAA,CAAO,YAAY,CAAC,CAAA;AAAA,UAC3D;AAAA,QACF,SAAS,CAAA,EAAG;AACV,UAAA,OAAA,GAAU,IAAA;AACV,UAAA,UAAA,CAAW,MAAM,CAAC,CAAA;AAAA,QACpB,CAAA,SAAE;AACA,UAAA,IAAI,CAAC,OAAA,EAAS;AACZ,YAAA,UAAA,CAAW,KAAA,EAAM;AAAA,UACnB;AAAA,QACF;AAAA,MACF;AAAA,KACD,CAAA;AAED,IAAA,OAAO,IAAI,SAAS,iBAAA,EAAmB;AAAA,MACrC,QAAQ,gBAAA,CAAiB,MAAA;AAAA,MACzB,YAAY,gBAAA,CAAiB,UAAA;AAAA,MAC7B,OAAA,EAAS,IAAI,OAAA,CAAQ,gBAAA,CAAiB,OAAO;AAAA,KAC9C,CAAA;AAAA,EACH,SAAS,CAAA,EAAG;AACV,IAAA,gBAAA,CAAiB,CAAA,EAAG;AAAA,MAClB,SAAA,EAAW,EAAE,IAAA,EAAM,yBAAA,EAA2B,SAAS,KAAA;AAAM,KAC9D,CAAA;AACD,IAAA,MAAM,CAAA;AAAA,EACR;AACF;AA0BO,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,OAAO,MAAM,SAAA;AAAA,cACX;AAAA,gBACE,IAAA,EAAM,CAAA,EAAG,MAAM,CAAA,CAAA,EAAI,IAAI,QAAQ,CAAA,CAAA;AAAA,gBAC/B,UAAA,EAAY;AAAA,kBACV,CAAC,gCAAgC,GAAG,oCAAA;AAAA,kBACpC,CAAC,SAAS,GAAG;AAAA;AACf,eACF;AAAA,cACA,YAAY;AACV,gBAAA,OAAO,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAA;AAAA,cACnC;AAAA,aACF;AAAA,UACF;AAEA,UAAA,IAAI,OAAO,8BAA8B,WAAA,EAAa;AACpD,YAAA,kCAAA,CAAmC,MAAA,EAAQ,GAAA,CAAI,QAAA,EAAU,yBAAyB,CAAA;AAAA,UACpF;AAEA,UAAA,OAAO,yBAAyB,MAAM,MAAA,CAAO,KAAA,CAAM,OAAA,EAAS,IAAI,CAAC,CAAA;AAAA,QACnE,CAAA,SAAE;AACA,UAAA,MAAM,iBAAA,EAAkB;AAAA,QAC1B;AAAA,MACF;AAAA,KACD,CAAA;AAAA,EACH;AACA,EAAA,OAAO,WAAA;AACT;;;;"}
@@ -1,3 +1,4 @@
1
+ import { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';
1
2
  import { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware.js';
2
3
  import { makeRoutePatternPlugin } from './routePatterns.js';
3
4
  import { makeAddSentryVitePlugin, makeEnableSourceMapsVitePlugin } from './sourceMaps.js';
@@ -11,6 +12,7 @@ function sentryTanstackStart(options = {}) {
11
12
  if (process.env.NODE_ENV === "development") {
12
13
  return plugins;
13
14
  }
15
+ plugins.push(sentryOrchestrionPlugin({ buildTimeInstrumentation: options.buildTimeInstrumentation }));
14
16
  plugins.push(...makeAddSentryVitePlugin(options));
15
17
  if (options.autoInstrumentMiddleware !== false) {
16
18
  plugins.push(makeAutoInstrumentMiddlewarePlugin({ enabled: true, debug: options.debug }));
@@ -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 { makeRoutePatternPlugin } from './routePatterns';\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 * Options related to react component name annotations.\n * Disabled by default, unless a value is set for this option.\n * When enabled, your app's DOM will automatically be annotated during build-time with their respective component names.\n * This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.\n * Please note that this feature is not currently supported by the esbuild bundler plugins, and will only annotate React components\n */\n reactComponentAnnotation?: {\n /**\n * Whether the component name annotate plugin should be enabled or not.\n */\n enabled?: boolean;\n\n /**\n * A list of strings representing the names of components to ignore. The plugin will not apply `data-sentry` annotations on the DOM element for these components.\n */\n ignoredComponents?: string[];\n };\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 plugins: Plugin[] = [makeRoutePatternPlugin()];\n\n if (options.tunnelRoute) {\n plugins.push(makeTunnelRoutePlugin(options.tunnelRoute, options.debug));\n }\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return plugins;\n }\n\n plugins.push(...makeAddSentryVitePlugin(options));\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":[],"mappings":";;;;;AAsFO,SAAS,mBAAA,CAAoB,OAAA,GAAsC,EAAC,EAAa;AACtF,EAAA,MAAM,OAAA,GAAoB,CAAC,sBAAA,EAAwB,CAAA;AAEnD,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,OAAA,CAAQ,KAAK,qBAAA,CAAsB,OAAA,CAAQ,WAAA,EAAa,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACxE;AAGA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,IAAA,OAAO,OAAA;AAAA,EACT;AAEA,EAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,uBAAA,CAAwB,OAAO,CAAC,CAAA;AAGhD,EAAA,IAAI,OAAA,CAAQ,6BAA6B,KAAA,EAAO;AAC9C,IAAA,OAAA,CAAQ,IAAA,CAAK,mCAAmC,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,GAAG,8BAAA,CAA+B,OAAO,CAAC,CAAA;AAAA,EACzD;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
1
+ {"version":3,"file":"sentryTanstackStart.js","sources":["../../../src/vite/sentryTanstackStart.ts"],"sourcesContent":["import type { BuildTimeOptionsBase } from '@sentry/core';\nimport { sentryOrchestrionPlugin } from '@sentry/server-utils/orchestrion/vite';\nimport type { Plugin } from 'vite';\nimport { makeAutoInstrumentMiddlewarePlugin } from './autoInstrumentMiddleware';\nimport { makeRoutePatternPlugin } from './routePatterns';\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 * Options related to react component name annotations.\n * Disabled by default, unless a value is set for this option.\n * When enabled, your app's DOM will automatically be annotated during build-time with their respective component names.\n * This will unlock the capability to search for Replays in Sentry by component name, as well as see component names in breadcrumbs and performance monitoring.\n * Please note that this feature is not currently supported by the esbuild bundler plugins, and will only annotate React components\n */\n reactComponentAnnotation?: {\n /**\n * Whether the component name annotate plugin should be enabled or not.\n */\n enabled?: boolean;\n\n /**\n * A list of strings representing the names of components to ignore. The plugin will not apply `data-sentry` annotations on the DOM element for these components.\n */\n ignoredComponents?: string[];\n };\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 plugins: Plugin[] = [makeRoutePatternPlugin()];\n\n if (options.tunnelRoute) {\n plugins.push(makeTunnelRoutePlugin(options.tunnelRoute, options.debug));\n }\n\n // only add build-time plugins in production builds\n if (process.env.NODE_ENV === 'development') {\n return plugins;\n }\n\n // Runs the orchestrion code transform over the server bundle so instrumented DB drivers get\n // `diagnostics_channel` publishers injected. Production-only: it force-bundles the instrumented\n // (CommonJS) deps via `ssr.noExternal`, which the `vite dev` SSR module runner can't evaluate.\n plugins.push(sentryOrchestrionPlugin({ buildTimeInstrumentation: options.buildTimeInstrumentation }));\n\n plugins.push(...makeAddSentryVitePlugin(options));\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":[],"mappings":";;;;;;AAuFO,SAAS,mBAAA,CAAoB,OAAA,GAAsC,EAAC,EAAa;AACtF,EAAA,MAAM,OAAA,GAAoB,CAAC,sBAAA,EAAwB,CAAA;AAEnD,EAAA,IAAI,QAAQ,WAAA,EAAa;AACvB,IAAA,OAAA,CAAQ,KAAK,qBAAA,CAAsB,OAAA,CAAQ,WAAA,EAAa,OAAA,CAAQ,KAAK,CAAC,CAAA;AAAA,EACxE;AAGA,EAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,QAAA,KAAa,aAAA,EAAe;AAC1C,IAAA,OAAO,OAAA;AAAA,EACT;AAKA,EAAA,OAAA,CAAQ,KAAK,uBAAA,CAAwB,EAAE,0BAA0B,OAAA,CAAQ,wBAAA,EAA0B,CAAC,CAAA;AAEpG,EAAA,OAAA,CAAQ,IAAA,CAAK,GAAG,uBAAA,CAAwB,OAAO,CAAC,CAAA;AAGhD,EAAA,IAAI,OAAA,CAAQ,6BAA6B,KAAA,EAAO;AAC9C,IAAA,OAAA,CAAQ,IAAA,CAAK,mCAAmC,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,GAAG,8BAAA,CAA+B,OAAO,CAAC,CAAA;AAAA,EACzD;AAEA,EAAA,OAAO,OAAA;AACT;;;;"}
@@ -1,4 +1,4 @@
1
- import { sentryVitePlugin } from '@sentry/vite-plugin';
1
+ import { sentryVitePlugin } from '@sentry/bundler-plugins/vite';
2
2
 
3
3
  function makeAddSentryVitePlugin(options) {
4
4
  const {
@@ -1 +1 @@
1
- {"version":3,"file":"sourceMaps.js","sources":["../../../src/vite/sourceMaps.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/vite-plugin';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryTanstackStartOptions } from './sentryTanstackStart';\n\ntype FilesToDeleteAfterUpload = string | string[] | undefined;\n\n/**\n * A Sentry plugin for adding the @sentry/vite-plugin to automatically upload source maps to Sentry.\n */\nexport function makeAddSentryVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n const {\n applicationKey,\n authToken,\n bundleSizeOptimizations,\n debug,\n errorHandler,\n headers,\n org,\n project,\n release,\n sentryUrl,\n silent,\n sourcemaps,\n telemetry,\n reactComponentAnnotation,\n } = options;\n\n // defer resolving the filesToDeleteAfterUpload until we got access to the Vite config\n let resolveFilesToDeleteAfterUpload: ((value: FilesToDeleteAfterUpload) => void) | undefined;\n const filesToDeleteAfterUploadPromise = new Promise<FilesToDeleteAfterUpload>(resolve => {\n resolveFilesToDeleteAfterUpload = resolve;\n });\n\n const configPlugin: Plugin = {\n name: 'sentry-tanstackstart-files-to-delete-after-upload-plugin',\n apply: 'build',\n enforce: 'post',\n config(config) {\n const userFilesToDelete = sourcemaps?.filesToDeleteAfterUpload;\n\n // Only auto-delete source maps if the user didn't configure sourcemaps at all\n if (typeof userFilesToDelete === 'undefined' && typeof config.build?.sourcemap === 'undefined') {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: [\"./**/*.map\"]` to delete generated source maps after they were uploaded to Sentry.',\n );\n }\n resolveFilesToDeleteAfterUpload?.(['./**/*.map']);\n } else {\n resolveFilesToDeleteAfterUpload?.(userFilesToDelete);\n }\n },\n };\n\n const sentryPlugins = sentryVitePlugin({\n applicationKey,\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations: bundleSizeOptimizations ?? undefined,\n debug: debug ?? false,\n errorHandler,\n headers,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n release,\n silent,\n sourcemaps: {\n assets: sourcemaps?.assets,\n disable: sourcemaps?.disable,\n ignore: sourcemaps?.ignore,\n // BuildTimeOptionsBase types can lag behind bundler plugin options in some local setups.\n // Keep runtime support while staying resilient to type version skew.\n rewriteSources: (sourcemaps as unknown as { rewriteSources?: unknown } | undefined)?.rewriteSources as never,\n filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n },\n telemetry: telemetry ?? true,\n url: sentryUrl,\n _metaOptions: {\n telemetry: {\n metaFramework: 'tanstackstart-react',\n },\n },\n });\n\n return [configPlugin, ...sentryPlugins];\n}\n\n/**\n * A Sentry plugin for TanStack Start React to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n return [\n {\n name: 'sentry-tanstackstart-react-source-maps',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n },\n ];\n}\n\n/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - We won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryTanstackStartOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteUserSourceMapSetting = viteConfig.build?.sourcemap;\n const settingKey = 'vite.build.sourcemap';\n const debug = sentryPluginOptions?.debug;\n\n // Respect user source map setting if it is explicitly set\n if (viteUserSourceMapSetting === false) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.warn(\n `[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.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Source map generation is disabled in your TanStack Start configuration.');\n }\n\n return viteUserSourceMapSetting;\n } else if (viteUserSourceMapSetting && ['hidden', 'inline', true].includes(viteUserSourceMapSetting)) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteUserSourceMapSetting.toString()}\\`. Sentry will keep this source map setting.`,\n );\n }\n\n return viteUserSourceMapSetting;\n }\n\n // If the user did not specify a source map setting, we enable 'hidden' by default\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n }\n\n return 'hidden';\n}\n"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sourceMaps.js","sources":["../../../src/vite/sourceMaps.ts"],"sourcesContent":["import { sentryVitePlugin } from '@sentry/bundler-plugins/vite';\nimport type { Plugin, UserConfig } from 'vite';\nimport type { SentryTanstackStartOptions } from './sentryTanstackStart';\n\ntype FilesToDeleteAfterUpload = string | string[] | undefined;\n\n/**\n * A Sentry plugin for adding the @sentry/bundler-plugins/vite to automatically upload source maps to Sentry.\n */\nexport function makeAddSentryVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n const {\n applicationKey,\n authToken,\n bundleSizeOptimizations,\n debug,\n errorHandler,\n headers,\n org,\n project,\n release,\n sentryUrl,\n silent,\n sourcemaps,\n telemetry,\n reactComponentAnnotation,\n } = options;\n\n // defer resolving the filesToDeleteAfterUpload until we got access to the Vite config\n let resolveFilesToDeleteAfterUpload: ((value: FilesToDeleteAfterUpload) => void) | undefined;\n const filesToDeleteAfterUploadPromise = new Promise<FilesToDeleteAfterUpload>(resolve => {\n resolveFilesToDeleteAfterUpload = resolve;\n });\n\n const configPlugin: Plugin = {\n name: 'sentry-tanstackstart-files-to-delete-after-upload-plugin',\n apply: 'build',\n enforce: 'post',\n config(config) {\n const userFilesToDelete = sourcemaps?.filesToDeleteAfterUpload;\n\n // Only auto-delete source maps if the user didn't configure sourcemaps at all\n if (typeof userFilesToDelete === 'undefined' && typeof config.build?.sourcemap === 'undefined') {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n '[Sentry] Automatically setting `sourcemaps.filesToDeleteAfterUpload: [\"./**/*.map\"]` to delete generated source maps after they were uploaded to Sentry.',\n );\n }\n resolveFilesToDeleteAfterUpload?.(['./**/*.map']);\n } else {\n resolveFilesToDeleteAfterUpload?.(userFilesToDelete);\n }\n },\n };\n\n const sentryPlugins = sentryVitePlugin({\n applicationKey,\n authToken: authToken ?? process.env.SENTRY_AUTH_TOKEN,\n bundleSizeOptimizations: bundleSizeOptimizations ?? undefined,\n debug: debug ?? false,\n errorHandler,\n headers,\n org: org ?? process.env.SENTRY_ORG,\n project: project ?? process.env.SENTRY_PROJECT,\n release,\n silent,\n sourcemaps: {\n assets: sourcemaps?.assets,\n disable: sourcemaps?.disable,\n ignore: sourcemaps?.ignore,\n // BuildTimeOptionsBase types can lag behind bundler plugin options in some local setups.\n // Keep runtime support while staying resilient to type version skew.\n rewriteSources: (sourcemaps as unknown as { rewriteSources?: unknown } | undefined)?.rewriteSources as never,\n filesToDeleteAfterUpload: filesToDeleteAfterUploadPromise,\n },\n reactComponentAnnotation: {\n enabled: reactComponentAnnotation?.enabled ?? undefined,\n ignoredComponents: reactComponentAnnotation?.ignoredComponents ?? undefined,\n },\n telemetry: telemetry ?? true,\n url: sentryUrl,\n _metaOptions: {\n telemetry: {\n metaFramework: 'tanstackstart-react',\n },\n },\n });\n\n return [configPlugin, ...sentryPlugins];\n}\n\n/**\n * A Sentry plugin for TanStack Start React to enable \"hidden\" source maps if they are unset.\n */\nexport function makeEnableSourceMapsVitePlugin(options: SentryTanstackStartOptions): Plugin[] {\n return [\n {\n name: 'sentry-tanstackstart-react-source-maps',\n apply: 'build',\n enforce: 'post',\n config(viteConfig) {\n return {\n ...viteConfig,\n build: {\n ...viteConfig.build,\n sourcemap: getUpdatedSourceMapSettings(viteConfig, options),\n },\n };\n },\n },\n ];\n}\n\n/** There are 3 ways to set up source map generation (https://github.com/getsentry/sentry-javascript/issues/13993)\n *\n * 1. User explicitly disabled source maps\n * - keep this setting (emit a warning that errors won't be unminified in Sentry)\n * - We won't upload anything\n *\n * 2. Users enabled source map generation (true, 'hidden', 'inline').\n * - keep this setting (don't do anything - like deletion - besides uploading)\n *\n * 3. Users didn't set source maps generation\n * - we enable 'hidden' source maps generation\n * - configure `filesToDeleteAfterUpload` to delete all .map files (we emit a log about this)\n *\n * --> only exported for testing\n */\nexport function getUpdatedSourceMapSettings(\n viteConfig: UserConfig,\n sentryPluginOptions?: SentryTanstackStartOptions,\n): boolean | 'inline' | 'hidden' {\n viteConfig.build = viteConfig.build || {};\n\n const viteUserSourceMapSetting = viteConfig.build?.sourcemap;\n const settingKey = 'vite.build.sourcemap';\n const debug = sentryPluginOptions?.debug;\n\n // Respect user source map setting if it is explicitly set\n if (viteUserSourceMapSetting === false) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.warn(\n `[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.`,\n );\n } else {\n // eslint-disable-next-line no-console\n console.warn('[Sentry] Source map generation is disabled in your TanStack Start configuration.');\n }\n\n return viteUserSourceMapSetting;\n } else if (viteUserSourceMapSetting && ['hidden', 'inline', true].includes(viteUserSourceMapSetting)) {\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] We discovered \\`${settingKey}\\` is set to \\`${viteUserSourceMapSetting.toString()}\\`. Sentry will keep this source map setting.`,\n );\n }\n\n return viteUserSourceMapSetting;\n }\n\n // If the user did not specify a source map setting, we enable 'hidden' by default\n if (debug) {\n // eslint-disable-next-line no-console\n console.log(\n `[Sentry] Enabled source map generation in the build options with \\`${settingKey}: 'hidden'\\`. The source maps will be deleted after they were uploaded to Sentry.`,\n );\n }\n\n return 'hidden';\n}\n"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- export { getFormat, getSource, load, resolve } from '@sentry/node/loader-hook';
1
+ import '@sentry/server-utils/orchestrion/import-hook';
@@ -10,6 +10,7 @@ export declare function init(options: Options | clientSdk.BrowserOptions | serve
10
10
  export declare const linkedErrorsIntegration: typeof clientSdk.linkedErrorsIntegration;
11
11
  export declare const contextLinesIntegration: typeof clientSdk.contextLinesIntegration;
12
12
  export declare const spanStreamingIntegration: typeof clientSdk.spanStreamingIntegration;
13
+ export declare const withStaticSpan: typeof clientSdk.withStaticSpan;
13
14
  export declare const withStreamedSpan: typeof clientSdk.withStreamedSpan;
14
15
  export declare const getDefaultIntegrations: (options: Options) => Integration[];
15
16
  export declare const defaultStackParser: StackParser;