@sentry/tanstackstart-react 10.31.0 → 10.32.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.
- package/build/cjs/index.server.js +2 -0
- package/build/cjs/index.server.js.map +1 -1
- package/build/cjs/server/index.js +2 -0
- package/build/cjs/server/index.js.map +1 -1
- package/build/cjs/server/utils.js +17 -0
- package/build/cjs/server/utils.js.map +1 -0
- package/build/cjs/server/wrapFetchWithSentry.js +69 -0
- package/build/cjs/server/wrapFetchWithSentry.js.map +1 -0
- package/build/esm/index.server.js +1 -0
- package/build/esm/index.server.js.map +1 -1
- package/build/esm/package.json +1 -1
- package/build/esm/server/index.js +1 -0
- package/build/esm/server/index.js.map +1 -1
- package/build/esm/server/utils.js +15 -0
- package/build/esm/server/utils.js.map +1 -0
- package/build/esm/server/wrapFetchWithSentry.js +67 -0
- package/build/esm/server/wrapFetchWithSentry.js.map +1 -0
- package/build/types/server/index.d.ts +1 -0
- package/build/types/server/index.d.ts.map +1 -1
- package/build/types/server/utils.d.ts +10 -0
- package/build/types/server/utils.d.ts.map +1 -0
- package/build/types/server/wrapFetchWithSentry.d.ts +29 -0
- package/build/types/server/wrapFetchWithSentry.d.ts.map +1 -0
- package/build/types-ts3.8/server/index.d.ts +1 -0
- package/build/types-ts3.8/server/utils.d.ts +10 -0
- package/build/types-ts3.8/server/wrapFetchWithSentry.d.ts +29 -0
- package/package.json +5 -5
|
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const index = require('./server/index.js');
|
|
4
4
|
const sdk = require('./server/sdk.js');
|
|
5
|
+
const wrapFetchWithSentry = require('./server/wrapFetchWithSentry.js');
|
|
5
6
|
const node = require('@sentry/node');
|
|
6
7
|
|
|
7
8
|
|
|
@@ -9,6 +10,7 @@ const node = require('@sentry/node');
|
|
|
9
10
|
exports.ErrorBoundary = index.ErrorBoundary;
|
|
10
11
|
exports.withErrorBoundary = index.withErrorBoundary;
|
|
11
12
|
exports.init = sdk.init;
|
|
13
|
+
exports.wrapFetchWithSentry = wrapFetchWithSentry.wrapFetchWithSentry;
|
|
12
14
|
Object.prototype.hasOwnProperty.call(node, '__proto__') &&
|
|
13
15
|
!Object.prototype.hasOwnProperty.call(exports, '__proto__') &&
|
|
14
16
|
Object.defineProperty(exports, '__proto__', {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -2,6 +2,7 @@ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
2
2
|
|
|
3
3
|
const node = require('@sentry/node');
|
|
4
4
|
const sdk = require('./sdk.js');
|
|
5
|
+
const wrapFetchWithSentry = require('./wrapFetchWithSentry.js');
|
|
5
6
|
|
|
6
7
|
// import/export got a false positive, and affects most of our index barrel files
|
|
7
8
|
// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703
|
|
@@ -35,6 +36,7 @@ function withErrorBoundary(
|
|
|
35
36
|
}
|
|
36
37
|
|
|
37
38
|
exports.init = sdk.init;
|
|
39
|
+
exports.wrapFetchWithSentry = wrapFetchWithSentry.wrapFetchWithSentry;
|
|
38
40
|
exports.ErrorBoundary = ErrorBoundary;
|
|
39
41
|
exports.withErrorBoundary = withErrorBoundary;
|
|
40
42
|
Object.prototype.hasOwnProperty.call(node, '__proto__') &&
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;;;AAAA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACO,MAAM,aAAA,GAAgB,CAAC,KAAK,KAAwD;AAC3F,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF,EAAE,IAAI,OAAO,KAAK,CAAC,QAAA,KAAa,UAAU,EAAE;AAC5C,IAAI,OAAO,CAAC,KAAK,CAAC,QAAA,IAAoC;AACtD,EAAE;;AAEF,EAAE,OAAO,KAAK,CAAC,QAAQ;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB;AACjC,EAAE,gBAAgB;AAClB,EAAe;AACf,EAAE,OAAO,gBAAA;AACT;;;;;;;;;;;;;;;;;"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Extracts the SHA-256 hash from a server function pathname.
|
|
5
|
+
* Server function pathnames are structured as `/_serverFn/<hash>`.
|
|
6
|
+
* This function matches the pattern and returns the hash if found.
|
|
7
|
+
*
|
|
8
|
+
* @param pathname - the pathname of the server function
|
|
9
|
+
* @returns the sha256 of the server function
|
|
10
|
+
*/
|
|
11
|
+
function extractServerFunctionSha256(pathname) {
|
|
12
|
+
const serverFnMatch = pathname.match(/\/_serverFn\/([a-f0-9]{64})/i);
|
|
13
|
+
return serverFnMatch?.[1] ?? 'unknown';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
exports.extractServerFunctionSha256 = extractServerFunctionSha256;
|
|
17
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["/**\n * Extracts the SHA-256 hash from a server function pathname.\n * Server function pathnames are structured as `/_serverFn/<hash>`.\n * This function matches the pattern and returns the hash if found.\n *\n * @param pathname - the pathname of the server function\n * @returns the sha256 of the server function\n */\nexport function extractServerFunctionSha256(pathname: string): string {\n const serverFnMatch = pathname.match(/\\/_serverFn\\/([a-f0-9]{64})/i);\n return serverFnMatch?.[1] ?? 'unknown';\n}\n"],"names":[],"mappings":";;AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B,CAAC,QAAQ,EAAkB;AACtE,EAAE,MAAM,gBAAgB,QAAQ,CAAC,KAAK,CAAC,8BAA8B,CAAC;AACtE,EAAE,OAAO,aAAa,GAAG,CAAC,CAAA,IAAK,SAAS;AACxC;;;;"}
|
|
@@ -0,0 +1,69 @@
|
|
|
1
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
+
|
|
3
|
+
const node = require('@sentry/node');
|
|
4
|
+
const utils = require('./utils.js');
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* This function can be used to wrap the server entry request handler to add tracing to server-side functionality.
|
|
8
|
+
* 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.
|
|
9
|
+
* For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* ```ts
|
|
13
|
+
* import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
|
|
14
|
+
*
|
|
15
|
+
* import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
16
|
+
* import type { ServerEntry } from '@tanstack/react-start/server-entry';
|
|
17
|
+
*
|
|
18
|
+
* const requestHandler: ServerEntry = wrapFetchWithSentry({
|
|
19
|
+
* fetch(request: Request) {
|
|
20
|
+
* return handler.fetch(request);
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* export default serverEntry = createServerEntry(requestHandler);
|
|
25
|
+
* ```
|
|
26
|
+
*
|
|
27
|
+
* @param serverEntry - request handler to wrap
|
|
28
|
+
* @returns - wrapped request handler
|
|
29
|
+
*/
|
|
30
|
+
function wrapFetchWithSentry(serverEntry) {
|
|
31
|
+
if (serverEntry.fetch) {
|
|
32
|
+
serverEntry.fetch = new Proxy(serverEntry.fetch, {
|
|
33
|
+
apply: (target, thisArg, args) => {
|
|
34
|
+
const request = args[0];
|
|
35
|
+
const url = new URL(request.url);
|
|
36
|
+
const method = request.method || 'GET';
|
|
37
|
+
|
|
38
|
+
// instrument server functions
|
|
39
|
+
if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {
|
|
40
|
+
const functionSha256 = utils.extractServerFunctionSha256(url.pathname);
|
|
41
|
+
const op = 'function.tanstackstart';
|
|
42
|
+
|
|
43
|
+
const serverFunctionSpanAttributes = {
|
|
44
|
+
[node.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',
|
|
45
|
+
[node.SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,
|
|
46
|
+
'tanstackstart.function.hash.sha256': functionSha256,
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
return node.startSpan(
|
|
50
|
+
{
|
|
51
|
+
op: op,
|
|
52
|
+
name: `${method} ${url.pathname}`,
|
|
53
|
+
attributes: serverFunctionSpanAttributes,
|
|
54
|
+
},
|
|
55
|
+
() => {
|
|
56
|
+
return target.apply(thisArg, args);
|
|
57
|
+
},
|
|
58
|
+
);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
return target.apply(thisArg, args);
|
|
62
|
+
},
|
|
63
|
+
});
|
|
64
|
+
}
|
|
65
|
+
return serverEntry;
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
exports.wrapFetchWithSentry = wrapFetchWithSentry;
|
|
69
|
+
//# sourceMappingURL=wrapFetchWithSentry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { extractServerFunctionSha256 } from './utils';\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function can be used to wrap the server entry request handler to add tracing to server-side functionality.\n * You must explicitly define a server entry point in your application for this to work. This is done by passing the request handler to the `createServerEntry` function.\n * For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).\n *\n * @example\n * ```ts\n * import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';\n *\n * import handler, { createServerEntry } from '@tanstack/react-start/server-entry';\n * import type { ServerEntry } from '@tanstack/react-start/server-entry';\n *\n * const requestHandler: ServerEntry = wrapFetchWithSentry({\n * fetch(request: Request) {\n * return handler.fetch(request);\n * },\n * });\n *\n * export default serverEntry = createServerEntry(requestHandler);\n * ```\n *\n * @param serverEntry - request handler to wrap\n * @returns - wrapped request handler\n */\nexport function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry {\n if (serverEntry.fetch) {\n serverEntry.fetch = new Proxy<typeof serverEntry.fetch>(serverEntry.fetch, {\n apply: (target, thisArg, args) => {\n const request: Request = args[0];\n const url = new URL(request.url);\n const method = request.method || 'GET';\n\n // instrument server functions\n if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {\n const functionSha256 = extractServerFunctionSha256(url.pathname);\n const op = 'function.tanstackstart';\n\n const serverFunctionSpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n 'tanstackstart.function.hash.sha256': functionSha256,\n };\n\n return startSpan(\n {\n op: op,\n name: `${method} ${url.pathname}`,\n attributes: serverFunctionSpanAttributes,\n },\n () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n return target.apply(thisArg, args);\n },\n });\n }\n return serverEntry;\n}\n"],"names":["extractServerFunctionSha256","SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN","SEMANTIC_ATTRIBUTE_SENTRY_OP","startSpan"],"mappings":";;;;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB,CAAC,WAAW,EAA4B;AAC3E,EAAE,IAAI,WAAW,CAAC,KAAK,EAAE;AACzB,IAAI,WAAW,CAAC,KAAA,GAAQ,IAAI,KAAK,CAA2B,WAAW,CAAC,KAAK,EAAE;AAC/E,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,KAAK;AACxC,QAAQ,MAAM,OAAO,GAAY,IAAI,CAAC,CAAC,CAAC;AACxC,QAAQ,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AACxC,QAAQ,MAAM,MAAA,GAAS,OAAO,CAAC,MAAA,IAAU,KAAK;;AAE9C;AACA,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,KAAK,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;AAC3F,UAAU,MAAM,iBAAiBA,iCAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC1E,UAAU,MAAM,EAAA,GAAK,wBAAwB;;AAE7C,UAAU,MAAM,+BAA+B;AAC/C,YAAY,CAACC,qCAAgC,GAAG,oCAAoC;AACpF,YAAY,CAACC,iCAA4B,GAAG,EAAE;AAC9C,YAAY,oCAAoC,EAAE,cAAc;AAChE,WAAW;;AAEX,UAAU,OAAOC,cAAS;AAC1B,YAAY;AACZ,cAAc,EAAE,EAAE,EAAE;AACpB,cAAc,IAAI,EAAE,CAAC,EAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,cAAA,UAAA,EAAA,4BAAA;AACA,aAAA;AACA,YAAA,MAAA;AACA,cAAA,OAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,YAAA,CAAA;AACA,WAAA;AACA,QAAA;;AAEA,QAAA,OAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,MAAA,CAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA,EAAA,OAAA,WAAA;AACA;;;;"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.server.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;"}
|
package/build/esm/package.json
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"type":"module","version":"10.
|
|
1
|
+
{"type":"module","version":"10.32.0-alpha.0","sideEffects":false}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/node';
|
|
2
2
|
export { init } from './sdk.js';
|
|
3
|
+
export { wrapFetchWithSentry } from './wrapFetchWithSentry.js';
|
|
3
4
|
|
|
4
5
|
// import/export got a false positive, and affects most of our index barrel files
|
|
5
6
|
// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../../../src/server/index.ts"],"sourcesContent":["// import/export got a false positive, and affects most of our index barrel files\n// can be removed once following issue is fixed: https://github.com/import-js/eslint-plugin-import/issues/703\n/* eslint-disable import/export */\nexport * from '@sentry/node';\n\nexport { init } from './sdk';\nexport { wrapFetchWithSentry } from './wrapFetchWithSentry';\n\n/**\n * A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors\n * so they should simply be a passthrough.\n */\nexport const ErrorBoundary = (props: React.PropsWithChildren<unknown>): React.ReactNode => {\n if (!props.children) {\n return null;\n }\n\n if (typeof props.children === 'function') {\n return (props.children as () => React.ReactNode)();\n }\n\n return props.children;\n};\n\n/**\n * A passthrough error boundary wrapper for the server that doesn't depend on any react. Error boundaries don't catch\n * SSR errors so they should simply be a passthrough.\n */\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function withErrorBoundary<P extends Record<string, any>>(\n WrappedComponent: React.ComponentType<P>,\n): React.FC<P> {\n return WrappedComponent as React.FC<P>;\n}\n"],"names":[],"mappings":";;;;AAAA;AACA;AACA;;AAMA;AACA;AACA;AACA;AACO,MAAM,aAAA,GAAgB,CAAC,KAAK,KAAwD;AAC3F,EAAE,IAAI,CAAC,KAAK,CAAC,QAAQ,EAAE;AACvB,IAAI,OAAO,IAAI;AACf,EAAE;;AAEF,EAAE,IAAI,OAAO,KAAK,CAAC,QAAA,KAAa,UAAU,EAAE;AAC5C,IAAI,OAAO,CAAC,KAAK,CAAC,QAAA,IAAoC;AACtD,EAAE;;AAEF,EAAE,OAAO,KAAK,CAAC,QAAQ;AACvB;;AAEA;AACA;AACA;AACA;AACA;AACO,SAAS,iBAAiB;AACjC,EAAE,gBAAgB;AAClB,EAAe;AACf,EAAE,OAAO,gBAAA;AACT;;;;"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the SHA-256 hash from a server function pathname.
|
|
3
|
+
* Server function pathnames are structured as `/_serverFn/<hash>`.
|
|
4
|
+
* This function matches the pattern and returns the hash if found.
|
|
5
|
+
*
|
|
6
|
+
* @param pathname - the pathname of the server function
|
|
7
|
+
* @returns the sha256 of the server function
|
|
8
|
+
*/
|
|
9
|
+
function extractServerFunctionSha256(pathname) {
|
|
10
|
+
const serverFnMatch = pathname.match(/\/_serverFn\/([a-f0-9]{64})/i);
|
|
11
|
+
return serverFnMatch?.[1] ?? 'unknown';
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export { extractServerFunctionSha256 };
|
|
15
|
+
//# sourceMappingURL=utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.js","sources":["../../../src/server/utils.ts"],"sourcesContent":["/**\n * Extracts the SHA-256 hash from a server function pathname.\n * Server function pathnames are structured as `/_serverFn/<hash>`.\n * This function matches the pattern and returns the hash if found.\n *\n * @param pathname - the pathname of the server function\n * @returns the sha256 of the server function\n */\nexport function extractServerFunctionSha256(pathname: string): string {\n const serverFnMatch = pathname.match(/\\/_serverFn\\/([a-f0-9]{64})/i);\n return serverFnMatch?.[1] ?? 'unknown';\n}\n"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,2BAA2B,CAAC,QAAQ,EAAkB;AACtE,EAAE,MAAM,gBAAgB,QAAQ,CAAC,KAAK,CAAC,8BAA8B,CAAC;AACtE,EAAE,OAAO,aAAa,GAAG,CAAC,CAAA,IAAK,SAAS;AACxC;;;;"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import { startSpan, SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '@sentry/node';
|
|
2
|
+
import { extractServerFunctionSha256 } from './utils.js';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* This function can be used to wrap the server entry request handler to add tracing to server-side functionality.
|
|
6
|
+
* 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.
|
|
7
|
+
* For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
|
|
12
|
+
*
|
|
13
|
+
* import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
14
|
+
* import type { ServerEntry } from '@tanstack/react-start/server-entry';
|
|
15
|
+
*
|
|
16
|
+
* const requestHandler: ServerEntry = wrapFetchWithSentry({
|
|
17
|
+
* fetch(request: Request) {
|
|
18
|
+
* return handler.fetch(request);
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* export default serverEntry = createServerEntry(requestHandler);
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @param serverEntry - request handler to wrap
|
|
26
|
+
* @returns - wrapped request handler
|
|
27
|
+
*/
|
|
28
|
+
function wrapFetchWithSentry(serverEntry) {
|
|
29
|
+
if (serverEntry.fetch) {
|
|
30
|
+
serverEntry.fetch = new Proxy(serverEntry.fetch, {
|
|
31
|
+
apply: (target, thisArg, args) => {
|
|
32
|
+
const request = args[0];
|
|
33
|
+
const url = new URL(request.url);
|
|
34
|
+
const method = request.method || 'GET';
|
|
35
|
+
|
|
36
|
+
// instrument server functions
|
|
37
|
+
if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {
|
|
38
|
+
const functionSha256 = extractServerFunctionSha256(url.pathname);
|
|
39
|
+
const op = 'function.tanstackstart';
|
|
40
|
+
|
|
41
|
+
const serverFunctionSpanAttributes = {
|
|
42
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',
|
|
43
|
+
[SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,
|
|
44
|
+
'tanstackstart.function.hash.sha256': functionSha256,
|
|
45
|
+
};
|
|
46
|
+
|
|
47
|
+
return startSpan(
|
|
48
|
+
{
|
|
49
|
+
op: op,
|
|
50
|
+
name: `${method} ${url.pathname}`,
|
|
51
|
+
attributes: serverFunctionSpanAttributes,
|
|
52
|
+
},
|
|
53
|
+
() => {
|
|
54
|
+
return target.apply(thisArg, args);
|
|
55
|
+
},
|
|
56
|
+
);
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return target.apply(thisArg, args);
|
|
60
|
+
},
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
return serverEntry;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export { wrapFetchWithSentry };
|
|
67
|
+
//# sourceMappingURL=wrapFetchWithSentry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapFetchWithSentry.js","sources":["../../../src/server/wrapFetchWithSentry.ts"],"sourcesContent":["import { SEMANTIC_ATTRIBUTE_SENTRY_OP, SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN, startSpan } from '@sentry/node';\nimport { extractServerFunctionSha256 } from './utils';\n\nexport type ServerEntry = {\n fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;\n};\n\n/**\n * This function can be used to wrap the server entry request handler to add tracing to server-side functionality.\n * You must explicitly define a server entry point in your application for this to work. This is done by passing the request handler to the `createServerEntry` function.\n * For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).\n *\n * @example\n * ```ts\n * import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';\n *\n * import handler, { createServerEntry } from '@tanstack/react-start/server-entry';\n * import type { ServerEntry } from '@tanstack/react-start/server-entry';\n *\n * const requestHandler: ServerEntry = wrapFetchWithSentry({\n * fetch(request: Request) {\n * return handler.fetch(request);\n * },\n * });\n *\n * export default serverEntry = createServerEntry(requestHandler);\n * ```\n *\n * @param serverEntry - request handler to wrap\n * @returns - wrapped request handler\n */\nexport function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry {\n if (serverEntry.fetch) {\n serverEntry.fetch = new Proxy<typeof serverEntry.fetch>(serverEntry.fetch, {\n apply: (target, thisArg, args) => {\n const request: Request = args[0];\n const url = new URL(request.url);\n const method = request.method || 'GET';\n\n // instrument server functions\n if (url.pathname.includes('_serverFn') || url.pathname.includes('createServerFn')) {\n const functionSha256 = extractServerFunctionSha256(url.pathname);\n const op = 'function.tanstackstart';\n\n const serverFunctionSpanAttributes = {\n [SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.tanstackstart.server',\n [SEMANTIC_ATTRIBUTE_SENTRY_OP]: op,\n 'tanstackstart.function.hash.sha256': functionSha256,\n };\n\n return startSpan(\n {\n op: op,\n name: `${method} ${url.pathname}`,\n attributes: serverFunctionSpanAttributes,\n },\n () => {\n return target.apply(thisArg, args);\n },\n );\n }\n\n return target.apply(thisArg, args);\n },\n });\n }\n return serverEntry;\n}\n"],"names":[],"mappings":";;;AAOA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAAS,mBAAmB,CAAC,WAAW,EAA4B;AAC3E,EAAE,IAAI,WAAW,CAAC,KAAK,EAAE;AACzB,IAAI,WAAW,CAAC,KAAA,GAAQ,IAAI,KAAK,CAA2B,WAAW,CAAC,KAAK,EAAE;AAC/E,MAAM,KAAK,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,KAAK;AACxC,QAAQ,MAAM,OAAO,GAAY,IAAI,CAAC,CAAC,CAAC;AACxC,QAAQ,MAAM,MAAM,IAAI,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC;AACxC,QAAQ,MAAM,MAAA,GAAS,OAAO,CAAC,MAAA,IAAU,KAAK;;AAE9C;AACA,QAAQ,IAAI,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,WAAW,KAAK,GAAG,CAAC,QAAQ,CAAC,QAAQ,CAAC,gBAAgB,CAAC,EAAE;AAC3F,UAAU,MAAM,iBAAiB,2BAA2B,CAAC,GAAG,CAAC,QAAQ,CAAC;AAC1E,UAAU,MAAM,EAAA,GAAK,wBAAwB;;AAE7C,UAAU,MAAM,+BAA+B;AAC/C,YAAY,CAAC,gCAAgC,GAAG,oCAAoC;AACpF,YAAY,CAAC,4BAA4B,GAAG,EAAE;AAC9C,YAAY,oCAAoC,EAAE,cAAc;AAChE,WAAW;;AAEX,UAAU,OAAO,SAAS;AAC1B,YAAY;AACZ,cAAc,EAAE,EAAE,EAAE;AACpB,cAAc,IAAI,EAAE,CAAC,EAAA,MAAA,CAAA,CAAA,EAAA,GAAA,CAAA,QAAA,CAAA,CAAA;AACA,cAAA,UAAA,EAAA,4BAAA;AACA,aAAA;AACA,YAAA,MAAA;AACA,cAAA,OAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,YAAA,CAAA;AACA,WAAA;AACA,QAAA;;AAEA,QAAA,OAAA,MAAA,CAAA,KAAA,CAAA,OAAA,EAAA,IAAA,CAAA;AACA,MAAA,CAAA;AACA,KAAA,CAAA;AACA,EAAA;AACA,EAAA,OAAA,WAAA;AACA;;;;"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/node';
|
|
2
2
|
export { init } from './sdk';
|
|
3
|
+
export { wrapFetchWithSentry } from './wrapFetchWithSentry';
|
|
3
4
|
/**
|
|
4
5
|
* A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors
|
|
5
6
|
* so they should simply be a passthrough.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAGA,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/server/index.ts"],"names":[],"mappings":"AAGA,cAAc,cAAc,CAAC;AAE7B,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,mBAAmB,EAAE,MAAM,uBAAuB,CAAC;AAE5D;;;GAGG;AACH,eAAO,MAAM,aAAa,GAAI,OAAO,KAAK,CAAC,iBAAiB,CAAC,OAAO,CAAC,KAAG,KAAK,CAAC,SAU7E,CAAC;AAEF;;;GAGG;AAEH,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC7D,gBAAgB,EAAE,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,GACvC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,CAEb"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the SHA-256 hash from a server function pathname.
|
|
3
|
+
* Server function pathnames are structured as `/_serverFn/<hash>`.
|
|
4
|
+
* This function matches the pattern and returns the hash if found.
|
|
5
|
+
*
|
|
6
|
+
* @param pathname - the pathname of the server function
|
|
7
|
+
* @returns the sha256 of the server function
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractServerFunctionSha256(pathname: string): string;
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/server/utils.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AACH,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGpE"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type ServerEntry = {
|
|
2
|
+
fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* This function can be used to wrap the server entry request handler to add tracing to server-side functionality.
|
|
6
|
+
* 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.
|
|
7
|
+
* For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
|
|
12
|
+
*
|
|
13
|
+
* import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
14
|
+
* import type { ServerEntry } from '@tanstack/react-start/server-entry';
|
|
15
|
+
*
|
|
16
|
+
* const requestHandler: ServerEntry = wrapFetchWithSentry({
|
|
17
|
+
* fetch(request: Request) {
|
|
18
|
+
* return handler.fetch(request);
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* export default serverEntry = createServerEntry(requestHandler);
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @param serverEntry - request handler to wrap
|
|
26
|
+
* @returns - wrapped request handler
|
|
27
|
+
*/
|
|
28
|
+
export declare function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry;
|
|
29
|
+
//# sourceMappingURL=wrapFetchWithSentry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"wrapFetchWithSentry.d.ts","sourceRoot":"","sources":["../../../src/server/wrapFetchWithSentry.ts"],"names":[],"mappings":"AAGA,MAAM,MAAM,WAAW,GAAG;IACxB,KAAK,EAAE,CAAC,OAAO,EAAE,OAAO,EAAE,IAAI,CAAC,EAAE,OAAO,KAAK,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;CAC3E,CAAC;AAEF;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AACH,wBAAgB,mBAAmB,CAAC,WAAW,EAAE,WAAW,GAAG,WAAW,CAoCzE"}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
export * from '@sentry/node';
|
|
2
2
|
export { init } from './sdk';
|
|
3
|
+
export { wrapFetchWithSentry } from './wrapFetchWithSentry';
|
|
3
4
|
/**
|
|
4
5
|
* A passthrough error boundary for the server that doesn't depend on any react. Error boundaries don't catch SSR errors
|
|
5
6
|
* so they should simply be a passthrough.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Extracts the SHA-256 hash from a server function pathname.
|
|
3
|
+
* Server function pathnames are structured as `/_serverFn/<hash>`.
|
|
4
|
+
* This function matches the pattern and returns the hash if found.
|
|
5
|
+
*
|
|
6
|
+
* @param pathname - the pathname of the server function
|
|
7
|
+
* @returns the sha256 of the server function
|
|
8
|
+
*/
|
|
9
|
+
export declare function extractServerFunctionSha256(pathname: string): string;
|
|
10
|
+
//# sourceMappingURL=utils.d.ts.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export type ServerEntry = {
|
|
2
|
+
fetch: (request: Request, opts?: unknown) => Promise<Response> | Response;
|
|
3
|
+
};
|
|
4
|
+
/**
|
|
5
|
+
* This function can be used to wrap the server entry request handler to add tracing to server-side functionality.
|
|
6
|
+
* 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.
|
|
7
|
+
* For more information about the server entry point, see the [TanStack Start documentation](https://tanstack.com/start/docs/server-entry).
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```ts
|
|
11
|
+
* import { wrapFetchWithSentry } from '@sentry/tanstackstart-react';
|
|
12
|
+
*
|
|
13
|
+
* import handler, { createServerEntry } from '@tanstack/react-start/server-entry';
|
|
14
|
+
* import type { ServerEntry } from '@tanstack/react-start/server-entry';
|
|
15
|
+
*
|
|
16
|
+
* const requestHandler: ServerEntry = wrapFetchWithSentry({
|
|
17
|
+
* fetch(request: Request) {
|
|
18
|
+
* return handler.fetch(request);
|
|
19
|
+
* },
|
|
20
|
+
* });
|
|
21
|
+
*
|
|
22
|
+
* export default serverEntry = createServerEntry(requestHandler);
|
|
23
|
+
* ```
|
|
24
|
+
*
|
|
25
|
+
* @param serverEntry - request handler to wrap
|
|
26
|
+
* @returns - wrapped request handler
|
|
27
|
+
*/
|
|
28
|
+
export declare function wrapFetchWithSentry(serverEntry: ServerEntry): ServerEntry;
|
|
29
|
+
//# sourceMappingURL=wrapFetchWithSentry.d.ts.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@sentry/tanstackstart-react",
|
|
3
|
-
"version": "10.
|
|
3
|
+
"version": "10.32.0-alpha.0",
|
|
4
4
|
"description": "Official Sentry SDK for TanStack Start React",
|
|
5
5
|
"repository": "git://github.com/getsentry/sentry-javascript.git",
|
|
6
6
|
"homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/tanstackstart-react",
|
|
@@ -52,10 +52,10 @@
|
|
|
52
52
|
"dependencies": {
|
|
53
53
|
"@opentelemetry/api": "^1.9.0",
|
|
54
54
|
"@opentelemetry/semantic-conventions": "^1.37.0",
|
|
55
|
-
"@sentry-internal/browser-utils": "10.
|
|
56
|
-
"@sentry/core": "10.
|
|
57
|
-
"@sentry/node": "10.
|
|
58
|
-
"@sentry/react": "10.
|
|
55
|
+
"@sentry-internal/browser-utils": "10.32.0-alpha.0",
|
|
56
|
+
"@sentry/core": "10.32.0-alpha.0",
|
|
57
|
+
"@sentry/node": "10.32.0-alpha.0",
|
|
58
|
+
"@sentry/react": "10.32.0-alpha.0"
|
|
59
59
|
},
|
|
60
60
|
"scripts": {
|
|
61
61
|
"build": "run-p build:transpile build:types",
|