@sentry/react 7.12.0 → 7.12.1

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/cjs/index.js CHANGED
@@ -24,6 +24,7 @@ exports.reactRouterV5Instrumentation = reactrouter.reactRouterV5Instrumentation;
24
24
  exports.withSentryRouting = reactrouter.withSentryRouting;
25
25
  exports.reactRouterV6Instrumentation = reactrouterv6.reactRouterV6Instrumentation;
26
26
  exports.withSentryReactRouterV6Routing = reactrouterv6.withSentryReactRouterV6Routing;
27
+ exports.wrapUseRoutes = reactrouterv6.wrapUseRoutes;
27
28
  for (var k in browser) {
28
29
  if (k !== 'default' && !exports.hasOwnProperty(k)) exports[k] = browser[k];
29
30
  }
package/cjs/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["export * from '@sentry/browser';\n\nexport { init } from './sdk';\nexport { Profiler, withProfiler, useProfiler } from './profiler';\nexport type { ErrorBoundaryProps, FallbackRender } from './errorboundary';\nexport { ErrorBoundary, withErrorBoundary } from './errorboundary';\nexport { createReduxEnhancer } from './redux';\nexport { reactRouterV3Instrumentation } from './reactrouterv3';\nexport { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';\nexport { reactRouterV6Instrumentation, withSentryReactRouterV6Routing } from './reactrouterv6';\n"],"names":[],"mappings":";;;;;;;;;;;AAIA;;;;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["export * from '@sentry/browser';\n\nexport { init } from './sdk';\nexport { Profiler, withProfiler, useProfiler } from './profiler';\nexport type { ErrorBoundaryProps, FallbackRender } from './errorboundary';\nexport { ErrorBoundary, withErrorBoundary } from './errorboundary';\nexport { createReduxEnhancer } from './redux';\nexport { reactRouterV3Instrumentation } from './reactrouterv3';\nexport { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';\nexport { reactRouterV6Instrumentation, withSentryReactRouterV6Routing, wrapUseRoutes } from './reactrouterv6';\n"],"names":[],"mappings":";;;;;;;;;;;AAIA;;;;;;;;;;;;;;;;;;"}
@@ -156,14 +156,13 @@ function withSentryRouting(Route) {
156
156
 
157
157
  var WrappedRoute = (props) => {
158
158
  if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {
159
- activeTransaction.setName(props.computedMatch.path);
160
- activeTransaction.setMetadata({ source: 'route' });
159
+ activeTransaction.setName(props.computedMatch.path, 'route');
161
160
  }
162
161
 
163
162
  // @ts-ignore Setting more specific React Component typing for `R` generic above
164
163
  // will break advanced type inference done by react router params:
165
164
  // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164
166
- return React__namespace.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 177}} );
165
+ return React__namespace.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 176}} );
167
166
  };
168
167
 
169
168
  WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import { Transaction, TransactionSource } from '@sentry/types';\nimport { getGlobalObject } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean };\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>;\n\nexport type RouteConfig = {\n [propName: string]: any;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\ntype MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst global = getGlobalObject<Window>();\n\nlet activeTransaction: Transaction | undefined;\n\nexport function reactRouterV4Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v4', routes, matchPath);\n}\n\nexport function reactRouterV5Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v5', routes, matchPath);\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n name: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (global && global.location) {\n return global.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n const tags = {\n 'routing.instrumentation': name,\n };\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n op: 'pageload',\n tags,\n metadata: {\n source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n op: 'navigation',\n tags,\n metadata: {\n source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {\n activeTransaction.setName(props.computedMatch.path);\n activeTransaction.setMetadata({ source: 'route' });\n }\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA;;AAOA;AACA;;AAoBA;;AAEA;;;;;;AAMA;;AAEA;;;;;;AAMA;;AAEA;;AAEA;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyEA;;AAEA;;;;AAIA;;;;;AAKA;;;;;;;;;;;;;;;;;;;;AAoBA;;AAEA;;AAEA;;;;;;;;;;;;;;;;;;;;;;;AAwBA;;;;"}
1
+ {"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import { Transaction, TransactionSource } from '@sentry/types';\nimport { getGlobalObject } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean };\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>;\n\nexport type RouteConfig = {\n [propName: string]: any;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\ntype MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst global = getGlobalObject<Window>();\n\nlet activeTransaction: Transaction | undefined;\n\nexport function reactRouterV4Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v4', routes, matchPath);\n}\n\nexport function reactRouterV5Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v5', routes, matchPath);\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n name: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (global && global.location) {\n return global.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n const tags = {\n 'routing.instrumentation': name,\n };\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n op: 'pageload',\n tags,\n metadata: {\n source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n op: 'navigation',\n tags,\n metadata: {\n source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {\n activeTransaction.setName(props.computedMatch.path, 'route');\n }\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA;;AAOA;AACA;;AAoBA;;AAEA;;;;;;AAMA;;AAEA;;;;;;AAMA;;AAEA;;AAEA;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAyEA;;AAEA;;;;AAIA;;;;;AAKA;;;;;;;;;;;;;;;;;;;;AAoBA;;AAEA;;AAEA;;;;;;;;;;;;;;;;;;;;;;AAuBA;;;;"}
@@ -107,6 +107,43 @@ function getNormalizedName(
107
107
  return [location.pathname, 'url'];
108
108
  }
109
109
 
110
+ function updatePageloadTransaction(location, routes) {
111
+ if (activeTransaction) {
112
+ activeTransaction.setName(...getNormalizedName(routes, location, _matchRoutes));
113
+ }
114
+ }
115
+
116
+ function handleNavigation(
117
+ location,
118
+ routes,
119
+ navigationType,
120
+ isBaseLocation,
121
+ ) {
122
+ if (isBaseLocation) {
123
+ if (activeTransaction) {
124
+ activeTransaction.finish();
125
+ }
126
+
127
+ return;
128
+ }
129
+
130
+ if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {
131
+ if (activeTransaction) {
132
+ activeTransaction.finish();
133
+ }
134
+
135
+ const [name, source] = getNormalizedName(routes, location, _matchRoutes);
136
+ activeTransaction = _customStartTransaction({
137
+ name,
138
+ op: 'navigation',
139
+ tags: SENTRY_TAGS,
140
+ metadata: {
141
+ source,
142
+ },
143
+ });
144
+ }
145
+ }
146
+
110
147
  function withSentryReactRouterV6Routing(Routes) {
111
148
  if (
112
149
  !_useEffect ||
@@ -135,45 +172,18 @@ function withSentryReactRouterV6Routing(Routes) {
135
172
  routes = _createRoutesFromChildren(props.children);
136
173
  isBaseLocation = true;
137
174
 
138
- if (activeTransaction) {
139
- const [name, source] = getNormalizedName(routes, location, _matchRoutes);
140
- activeTransaction.setName(name);
141
- activeTransaction.setMetadata({ source });
142
- }
143
-
175
+ updatePageloadTransaction(location, routes);
144
176
  }, [props.children]);
145
177
 
146
178
  _useEffect(() => {
147
- if (isBaseLocation) {
148
- if (activeTransaction) {
149
- activeTransaction.finish();
150
- }
151
-
152
- return;
153
- }
154
-
155
- if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {
156
- if (activeTransaction) {
157
- activeTransaction.finish();
158
- }
159
-
160
- const [name, source] = getNormalizedName(routes, location, _matchRoutes);
161
- activeTransaction = _customStartTransaction({
162
- name,
163
- op: 'navigation',
164
- tags: SENTRY_TAGS,
165
- metadata: {
166
- source,
167
- },
168
- });
169
- }
179
+ handleNavigation(location, routes, navigationType, isBaseLocation);
170
180
  }, [props.children, location, navigationType, isBaseLocation]);
171
181
 
172
182
  isBaseLocation = false;
173
183
 
174
184
  // @ts-ignore Setting more specific React Component typing for `R` generic above
175
185
  // will break advanced type inference done by react router params
176
- return React__default.createElement(Routes, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 211}} );
186
+ return React__default.createElement(Routes, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 223}} );
177
187
  };
178
188
 
179
189
  hoistNonReactStatics__default(SentryRoutes, Routes);
@@ -183,6 +193,46 @@ function withSentryReactRouterV6Routing(Routes) {
183
193
  return SentryRoutes;
184
194
  }
185
195
 
196
+ function wrapUseRoutes(origUseRoutes) {
197
+ if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) {
198
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
199
+ utils.logger.warn(
200
+ 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.',
201
+ );
202
+
203
+ return origUseRoutes;
204
+ }
205
+
206
+ let isBaseLocation = false;
207
+
208
+ return (routes, location) => {
209
+ var SentryRoutes = (props) => {
210
+ var Routes = origUseRoutes(routes, location);
211
+
212
+ var locationArgObject = typeof location === 'string' ? { pathname: location } : location;
213
+ var locationObject = (locationArgObject ) || _useLocation();
214
+ var navigationType = _useNavigationType();
215
+
216
+ _useEffect(() => {
217
+ isBaseLocation = true;
218
+
219
+ updatePageloadTransaction(locationObject, routes);
220
+ }, [props]);
221
+
222
+ _useEffect(() => {
223
+ handleNavigation(locationObject, routes, navigationType, isBaseLocation);
224
+ }, [props, locationObject, navigationType, isBaseLocation]);
225
+
226
+ isBaseLocation = false;
227
+
228
+ return Routes;
229
+ };
230
+
231
+ return React__default.createElement(SentryRoutes, {__self: this, __source: {fileName: _jsxFileName, lineNumber: 268}} );
232
+ };
233
+ }
234
+
186
235
  exports.reactRouterV6Instrumentation = reactRouterV6Instrumentation;
187
236
  exports.withSentryReactRouterV6Routing = withSentryReactRouterV6Routing;
237
+ exports.wrapUseRoutes = wrapUseRoutes;
188
238
  //# sourceMappingURL=reactrouterv6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouterv6.js","sources":["../../src/reactrouterv6.tsx"],"sourcesContent":["// Inspired from Donnie McNeal's solution:\n// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536\n\nimport { Transaction, TransactionContext, TransactionSource } from '@sentry/types';\nimport { getGlobalObject, getNumberOfUrlSegments, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport React from 'react';\n\nimport { Action, Location } from './types';\n\ninterface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\ntype Params<Key extends string = string> = {\n readonly [key in Key]: string | undefined;\n};\n\n// https://github.com/remix-run/react-router/blob/9fa54d643134cd75a0335581a75db8100ed42828/packages/react-router/lib/router.ts#L114-L134\ninterface RouteMatch<ParamKey extends string = string> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params<ParamKey>;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObject;\n}\n\ntype UseEffect = (cb: () => void, deps: unknown[]) => void;\ntype UseLocation = () => Location;\ntype UseNavigationType = () => Action;\ntype CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject[];\ntype MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;\n\nlet activeTransaction: Transaction | undefined;\n\nlet _useEffect: UseEffect;\nlet _useLocation: UseLocation;\nlet _useNavigationType: UseNavigationType;\nlet _createRoutesFromChildren: CreateRoutesFromChildren;\nlet _matchRoutes: MatchRoutes;\nlet _customStartTransaction: (context: TransactionContext) => Transaction | undefined;\nlet _startTransactionOnLocationChange: boolean;\n\nconst global = getGlobalObject<Window>();\n\nconst SENTRY_TAGS = {\n 'routing.instrumentation': 'react-router-v6',\n};\n\nexport function reactRouterV6Instrumentation(\n useEffect: UseEffect,\n useLocation: UseLocation,\n useNavigationType: UseNavigationType,\n createRoutesFromChildren: CreateRoutesFromChildren,\n matchRoutes: MatchRoutes,\n) {\n return (\n customStartTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad = true,\n startTransactionOnLocationChange = true,\n ): void => {\n const initPathName = global && global.location && global.location.pathname;\n if (startTransactionOnPageLoad && initPathName) {\n activeTransaction = customStartTransaction({\n name: initPathName,\n op: 'pageload',\n tags: SENTRY_TAGS,\n metadata: {\n source: 'url',\n },\n });\n }\n\n _useEffect = useEffect;\n _useLocation = useLocation;\n _useNavigationType = useNavigationType;\n _matchRoutes = matchRoutes;\n _createRoutesFromChildren = createRoutesFromChildren;\n\n _customStartTransaction = customStartTransaction;\n _startTransactionOnLocationChange = startTransactionOnLocationChange;\n };\n}\n\nfunction getNormalizedName(\n routes: RouteObject[],\n location: Location,\n matchRoutes: MatchRoutes,\n): [string, TransactionSource] {\n if (!routes || routes.length === 0 || !matchRoutes) {\n return [location.pathname, 'url'];\n }\n\n const branches = matchRoutes(routes, location);\n\n let pathBuilder = '';\n if (branches) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n const branch = branches[x];\n const route = branch.route;\n if (route) {\n // Early return if index route\n if (route.index) {\n return [branch.pathname, 'route'];\n }\n\n const path = route.path;\n if (path) {\n const newPath = path[0] === '/' ? path : `/${path}`;\n pathBuilder += newPath;\n if (branch.pathname === location.pathname) {\n // If the route defined on the element is something like\n // <Route path=\"/stores/:storeId/products/:productId\" element={<div>Product</div>} />\n // We should check against the branch.pathname for the number of / seperators\n if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname)) {\n return [newPath, 'route'];\n }\n return [pathBuilder, 'route'];\n }\n }\n }\n }\n }\n\n return [location.pathname, 'url'];\n}\n\nexport function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R {\n if (\n !_useEffect ||\n !_useLocation ||\n !_useNavigationType ||\n !_createRoutesFromChildren ||\n !_matchRoutes ||\n !_customStartTransaction\n ) {\n __DEBUG_BUILD__ &&\n logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');\n\n return Routes;\n }\n\n let isBaseLocation: boolean = false;\n let routes: RouteObject[];\n\n const SentryRoutes: React.FC<P> = (props: P) => {\n const location = _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n // Performance concern:\n // This is repeated when <Routes /> is rendered.\n routes = _createRoutesFromChildren(props.children);\n isBaseLocation = true;\n\n if (activeTransaction) {\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction.setName(name);\n activeTransaction.setMetadata({ source });\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.children]);\n\n _useEffect(() => {\n if (isBaseLocation) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n return;\n }\n\n if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction = _customStartTransaction({\n name,\n op: 'navigation',\n tags: SENTRY_TAGS,\n metadata: {\n source,\n },\n });\n }\n }, [props.children, location, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return <Routes {...props} />;\n };\n\n hoistNonReactStatics(SentryRoutes, Routes);\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return SentryRoutes;\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAAA;;AAgDA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA;;AAEA;;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA;;;"}
1
+ {"version":3,"file":"reactrouterv6.js","sources":["../../src/reactrouterv6.tsx"],"sourcesContent":["// Inspired from Donnie McNeal's solution:\n// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536\n\nimport { Transaction, TransactionContext, TransactionSource } from '@sentry/types';\nimport { getGlobalObject, getNumberOfUrlSegments, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport React from 'react';\n\nimport { Action, Location } from './types';\n\ninterface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\ntype Params<Key extends string = string> = {\n readonly [key in Key]: string | undefined;\n};\n\ntype UseRoutes = (routes: RouteObject[], locationArg?: Partial<Location> | string) => React.ReactElement | null;\n\n// https://github.com/remix-run/react-router/blob/9fa54d643134cd75a0335581a75db8100ed42828/packages/react-router/lib/router.ts#L114-L134\ninterface RouteMatch<ParamKey extends string = string> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params<ParamKey>;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObject;\n}\n\ntype UseEffect = (cb: () => void, deps: unknown[]) => void;\ntype UseLocation = () => Location;\ntype UseNavigationType = () => Action;\ntype CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject[];\ntype MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;\n\nlet activeTransaction: Transaction | undefined;\n\nlet _useEffect: UseEffect;\nlet _useLocation: UseLocation;\nlet _useNavigationType: UseNavigationType;\nlet _createRoutesFromChildren: CreateRoutesFromChildren;\nlet _matchRoutes: MatchRoutes;\nlet _customStartTransaction: (context: TransactionContext) => Transaction | undefined;\nlet _startTransactionOnLocationChange: boolean;\n\nconst global = getGlobalObject<Window>();\n\nconst SENTRY_TAGS = {\n 'routing.instrumentation': 'react-router-v6',\n};\n\nexport function reactRouterV6Instrumentation(\n useEffect: UseEffect,\n useLocation: UseLocation,\n useNavigationType: UseNavigationType,\n createRoutesFromChildren: CreateRoutesFromChildren,\n matchRoutes: MatchRoutes,\n) {\n return (\n customStartTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad = true,\n startTransactionOnLocationChange = true,\n ): void => {\n const initPathName = global && global.location && global.location.pathname;\n if (startTransactionOnPageLoad && initPathName) {\n activeTransaction = customStartTransaction({\n name: initPathName,\n op: 'pageload',\n tags: SENTRY_TAGS,\n metadata: {\n source: 'url',\n },\n });\n }\n\n _useEffect = useEffect;\n _useLocation = useLocation;\n _useNavigationType = useNavigationType;\n _matchRoutes = matchRoutes;\n _createRoutesFromChildren = createRoutesFromChildren;\n\n _customStartTransaction = customStartTransaction;\n _startTransactionOnLocationChange = startTransactionOnLocationChange;\n };\n}\n\nfunction getNormalizedName(\n routes: RouteObject[],\n location: Location,\n matchRoutes: MatchRoutes,\n): [string, TransactionSource] {\n if (!routes || routes.length === 0 || !matchRoutes) {\n return [location.pathname, 'url'];\n }\n\n const branches = matchRoutes(routes, location);\n\n let pathBuilder = '';\n if (branches) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n const branch = branches[x];\n const route = branch.route;\n if (route) {\n // Early return if index route\n if (route.index) {\n return [branch.pathname, 'route'];\n }\n\n const path = route.path;\n if (path) {\n const newPath = path[0] === '/' ? path : `/${path}`;\n pathBuilder += newPath;\n if (branch.pathname === location.pathname) {\n // If the route defined on the element is something like\n // <Route path=\"/stores/:storeId/products/:productId\" element={<div>Product</div>} />\n // We should check against the branch.pathname for the number of / seperators\n if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname)) {\n return [newPath, 'route'];\n }\n return [pathBuilder, 'route'];\n }\n }\n }\n }\n }\n\n return [location.pathname, 'url'];\n}\n\nfunction updatePageloadTransaction(location: Location, routes: RouteObject[]): void {\n if (activeTransaction) {\n activeTransaction.setName(...getNormalizedName(routes, location, _matchRoutes));\n }\n}\n\nfunction handleNavigation(\n location: Location,\n routes: RouteObject[],\n navigationType: Action,\n isBaseLocation: boolean,\n): void {\n if (isBaseLocation) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n return;\n }\n\n if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction = _customStartTransaction({\n name,\n op: 'navigation',\n tags: SENTRY_TAGS,\n metadata: {\n source,\n },\n });\n }\n}\n\nexport function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R {\n if (\n !_useEffect ||\n !_useLocation ||\n !_useNavigationType ||\n !_createRoutesFromChildren ||\n !_matchRoutes ||\n !_customStartTransaction\n ) {\n __DEBUG_BUILD__ &&\n logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');\n\n return Routes;\n }\n\n let isBaseLocation: boolean = false;\n let routes: RouteObject[];\n\n const SentryRoutes: React.FC<P> = (props: P) => {\n const location = _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n // Performance concern:\n // This is repeated when <Routes /> is rendered.\n routes = _createRoutesFromChildren(props.children);\n isBaseLocation = true;\n\n updatePageloadTransaction(location, routes);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.children]);\n\n _useEffect(() => {\n handleNavigation(location, routes, navigationType, isBaseLocation);\n }, [props.children, location, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return <Routes {...props} />;\n };\n\n hoistNonReactStatics(SentryRoutes, Routes);\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return SentryRoutes;\n}\n\nexport function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes {\n if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) {\n __DEBUG_BUILD__ &&\n logger.warn(\n 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.',\n );\n\n return origUseRoutes;\n }\n\n let isBaseLocation: boolean = false;\n\n return (routes: RouteObject[], location?: Partial<Location> | string): React.ReactElement | null => {\n const SentryRoutes: React.FC<unknown> = (props: unknown) => {\n const Routes = origUseRoutes(routes, location);\n\n const locationArgObject = typeof location === 'string' ? { pathname: location } : location;\n const locationObject = (locationArgObject as Location) || _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n isBaseLocation = true;\n\n updatePageloadTransaction(locationObject, routes);\n }, [props]);\n\n _useEffect(() => {\n handleNavigation(locationObject, routes, navigationType, isBaseLocation);\n }, [props, locationObject, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n return Routes;\n };\n\n return <SentryRoutes />;\n };\n}\n"],"names":[],"mappings":";;;;;;;;;;;;;AAAA;;AAkDA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;;AAEA;;AAEA;;;;;;;;AAQA;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA;;AAEA;;;;AAIA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAsCA;;AAEA;;;;AAIA;;AAEA;;;;;AAKA;;;;;;;;;;;;;;;;;;;;;;;;AAwBA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAuCA;;;;"}
package/esm/index.js CHANGED
@@ -5,7 +5,7 @@ export { ErrorBoundary, withErrorBoundary } from './errorboundary.js';
5
5
  export { createReduxEnhancer } from './redux.js';
6
6
  export { reactRouterV3Instrumentation } from './reactrouterv3.js';
7
7
  export { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter.js';
8
- export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing } from './reactrouterv6.js';
8
+ export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing, wrapUseRoutes } from './reactrouterv6.js';
9
9
 
10
10
  ;
11
11
  //# sourceMappingURL=index.js.map
package/esm/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["export * from '@sentry/browser';\n\nexport { init } from './sdk';\nexport { Profiler, withProfiler, useProfiler } from './profiler';\nexport type { ErrorBoundaryProps, FallbackRender } from './errorboundary';\nexport { ErrorBoundary, withErrorBoundary } from './errorboundary';\nexport { createReduxEnhancer } from './redux';\nexport { reactRouterV3Instrumentation } from './reactrouterv3';\nexport { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';\nexport { reactRouterV6Instrumentation, withSentryReactRouterV6Routing } from './reactrouterv6';\n"],"names":[],"mappings":";;;;;;;;;AAIA"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["export * from '@sentry/browser';\n\nexport { init } from './sdk';\nexport { Profiler, withProfiler, useProfiler } from './profiler';\nexport type { ErrorBoundaryProps, FallbackRender } from './errorboundary';\nexport { ErrorBoundary, withErrorBoundary } from './errorboundary';\nexport { createReduxEnhancer } from './redux';\nexport { reactRouterV3Instrumentation } from './reactrouterv3';\nexport { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';\nexport { reactRouterV6Instrumentation, withSentryReactRouterV6Routing, wrapUseRoutes } from './reactrouterv6';\n"],"names":[],"mappings":";;;;;;;;;AAIA"}
@@ -146,14 +146,13 @@ function withSentryRouting(Route) {
146
146
 
147
147
  var WrappedRoute = (props) => {
148
148
  if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {
149
- activeTransaction.setName(props.computedMatch.path);
150
- activeTransaction.setMetadata({ source: 'route' });
149
+ activeTransaction.setName(props.computedMatch.path, 'route');
151
150
  }
152
151
 
153
152
  // @ts-ignore Setting more specific React Component typing for `R` generic above
154
153
  // will break advanced type inference done by react router params:
155
154
  // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164
156
- return React.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 177}} );
155
+ return React.createElement(Route, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 176}} );
157
156
  };
158
157
 
159
158
  WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import { Transaction, TransactionSource } from '@sentry/types';\nimport { getGlobalObject } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean };\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>;\n\nexport type RouteConfig = {\n [propName: string]: any;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\ntype MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst global = getGlobalObject<Window>();\n\nlet activeTransaction: Transaction | undefined;\n\nexport function reactRouterV4Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v4', routes, matchPath);\n}\n\nexport function reactRouterV5Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v5', routes, matchPath);\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n name: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (global && global.location) {\n return global.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n const tags = {\n 'routing.instrumentation': name,\n };\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n op: 'pageload',\n tags,\n metadata: {\n source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n op: 'navigation',\n tags,\n metadata: {\n source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {\n activeTransaction.setName(props.computedMatch.path);\n activeTransaction.setMetadata({ source: 'route' });\n }\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n"],"names":[],"mappings":";;;;AAAA;;AAOA;AACA;;AAoBA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"reactrouter.js","sources":["../../src/reactrouter.tsx"],"sourcesContent":["import { Transaction, TransactionSource } from '@sentry/types';\nimport { getGlobalObject } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport * as React from 'react';\n\nimport { Action, Location, ReactRouterInstrumentation } from './types';\n\n// We need to disable eslint no-explict-any because any is required for the\n// react-router typings.\n/* eslint-disable @typescript-eslint/no-explicit-any */\ntype Match = { path: string; url: string; params: Record<string, any>; isExact: boolean };\n\nexport type RouterHistory = {\n location?: Location;\n listen?(cb: (location: Location, action: Action) => void): void;\n} & Record<string, any>;\n\nexport type RouteConfig = {\n [propName: string]: any;\n path?: string | string[];\n exact?: boolean;\n component?: JSX.Element;\n routes?: RouteConfig[];\n};\n\ntype MatchPath = (pathname: string, props: string | string[] | any, parent?: Match | null) => Match | null;\n/* eslint-enable @typescript-eslint/no-explicit-any */\n\nconst global = getGlobalObject<Window>();\n\nlet activeTransaction: Transaction | undefined;\n\nexport function reactRouterV4Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v4', routes, matchPath);\n}\n\nexport function reactRouterV5Instrumentation(\n history: RouterHistory,\n routes?: RouteConfig[],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n return createReactRouterInstrumentation(history, 'react-router-v5', routes, matchPath);\n}\n\nfunction createReactRouterInstrumentation(\n history: RouterHistory,\n name: string,\n allRoutes: RouteConfig[] = [],\n matchPath?: MatchPath,\n): ReactRouterInstrumentation {\n function getInitPathName(): string | undefined {\n if (history && history.location) {\n return history.location.pathname;\n }\n\n if (global && global.location) {\n return global.location.pathname;\n }\n\n return undefined;\n }\n\n /**\n * Normalizes a transaction name. Returns the new name as well as the\n * source of the transaction.\n *\n * @param pathname The initial pathname we normalize\n */\n function normalizeTransactionName(pathname: string): [string, TransactionSource] {\n if (allRoutes.length === 0 || !matchPath) {\n return [pathname, 'url'];\n }\n\n const branches = matchRoutes(allRoutes, pathname, matchPath);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n if (branches[x].match.isExact) {\n return [branches[x].match.path, 'route'];\n }\n }\n\n return [pathname, 'url'];\n }\n\n const tags = {\n 'routing.instrumentation': name,\n };\n\n return (customStartTransaction, startTransactionOnPageLoad = true, startTransactionOnLocationChange = true): void => {\n const initPathName = getInitPathName();\n if (startTransactionOnPageLoad && initPathName) {\n const [name, source] = normalizeTransactionName(initPathName);\n activeTransaction = customStartTransaction({\n name,\n op: 'pageload',\n tags,\n metadata: {\n source,\n },\n });\n }\n\n if (startTransactionOnLocationChange && history.listen) {\n history.listen((location, action) => {\n if (action && (action === 'PUSH' || action === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = normalizeTransactionName(location.pathname);\n activeTransaction = customStartTransaction({\n name,\n op: 'navigation',\n tags,\n metadata: {\n source,\n },\n });\n }\n });\n }\n };\n}\n\n/**\n * Matches a set of routes to a pathname\n * Based on implementation from\n */\nfunction matchRoutes(\n routes: RouteConfig[],\n pathname: string,\n matchPath: MatchPath,\n branch: Array<{ route: RouteConfig; match: Match }> = [],\n): Array<{ route: RouteConfig; match: Match }> {\n routes.some(route => {\n const match = route.path\n ? matchPath(pathname, route)\n : branch.length\n ? branch[branch.length - 1].match // use parent match\n : computeRootMatch(pathname); // use default \"root\" match\n\n if (match) {\n branch.push({ route, match });\n\n if (route.routes) {\n matchRoutes(route.routes, pathname, matchPath, branch);\n }\n }\n\n return !!match;\n });\n\n return branch;\n}\n\nfunction computeRootMatch(pathname: string): Match {\n return { path: '/', url: '/', params: {}, isExact: pathname === '/' };\n}\n\n/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\nexport function withSentryRouting<P extends Record<string, any>, R extends React.ComponentType<P>>(Route: R): R {\n const componentDisplayName = (Route as any).displayName || (Route as any).name;\n\n const WrappedRoute: React.FC<P> = (props: P) => {\n if (activeTransaction && props && props.computedMatch && props.computedMatch.isExact) {\n activeTransaction.setName(props.computedMatch.path, 'route');\n }\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return <Route {...props} />;\n };\n\n WrappedRoute.displayName = `sentryRoute(${componentDisplayName})`;\n hoistNonReactStatics(WrappedRoute, Route);\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params:\n // https://github.com/DefinitelyTyped/DefinitelyTyped/blob/13dc4235c069e25fe7ee16e11f529d909f9f3ff8/types/react-router/index.d.ts#L154-L164\n return WrappedRoute;\n}\n/* eslint-enable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access */\n"],"names":[],"mappings":";;;;AAAA;;AAOA;AACA;;AAoBA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAGA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
@@ -98,6 +98,43 @@ function getNormalizedName(
98
98
  return [location.pathname, 'url'];
99
99
  }
100
100
 
101
+ function updatePageloadTransaction(location, routes) {
102
+ if (activeTransaction) {
103
+ activeTransaction.setName(...getNormalizedName(routes, location, _matchRoutes));
104
+ }
105
+ }
106
+
107
+ function handleNavigation(
108
+ location,
109
+ routes,
110
+ navigationType,
111
+ isBaseLocation,
112
+ ) {
113
+ if (isBaseLocation) {
114
+ if (activeTransaction) {
115
+ activeTransaction.finish();
116
+ }
117
+
118
+ return;
119
+ }
120
+
121
+ if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {
122
+ if (activeTransaction) {
123
+ activeTransaction.finish();
124
+ }
125
+
126
+ const [name, source] = getNormalizedName(routes, location, _matchRoutes);
127
+ activeTransaction = _customStartTransaction({
128
+ name,
129
+ op: 'navigation',
130
+ tags: SENTRY_TAGS,
131
+ metadata: {
132
+ source,
133
+ },
134
+ });
135
+ }
136
+ }
137
+
101
138
  function withSentryReactRouterV6Routing(Routes) {
102
139
  if (
103
140
  !_useEffect ||
@@ -126,45 +163,18 @@ function withSentryReactRouterV6Routing(Routes) {
126
163
  routes = _createRoutesFromChildren(props.children);
127
164
  isBaseLocation = true;
128
165
 
129
- if (activeTransaction) {
130
- const [name, source] = getNormalizedName(routes, location, _matchRoutes);
131
- activeTransaction.setName(name);
132
- activeTransaction.setMetadata({ source });
133
- }
134
-
166
+ updatePageloadTransaction(location, routes);
135
167
  }, [props.children]);
136
168
 
137
169
  _useEffect(() => {
138
- if (isBaseLocation) {
139
- if (activeTransaction) {
140
- activeTransaction.finish();
141
- }
142
-
143
- return;
144
- }
145
-
146
- if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {
147
- if (activeTransaction) {
148
- activeTransaction.finish();
149
- }
150
-
151
- const [name, source] = getNormalizedName(routes, location, _matchRoutes);
152
- activeTransaction = _customStartTransaction({
153
- name,
154
- op: 'navigation',
155
- tags: SENTRY_TAGS,
156
- metadata: {
157
- source,
158
- },
159
- });
160
- }
170
+ handleNavigation(location, routes, navigationType, isBaseLocation);
161
171
  }, [props.children, location, navigationType, isBaseLocation]);
162
172
 
163
173
  isBaseLocation = false;
164
174
 
165
175
  // @ts-ignore Setting more specific React Component typing for `R` generic above
166
176
  // will break advanced type inference done by react router params
167
- return React__default.createElement(Routes, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 211}} );
177
+ return React__default.createElement(Routes, { ...props, __self: this, __source: {fileName: _jsxFileName, lineNumber: 223}} );
168
178
  };
169
179
 
170
180
  hoistNonReactStatics(SentryRoutes, Routes);
@@ -174,5 +184,44 @@ function withSentryReactRouterV6Routing(Routes) {
174
184
  return SentryRoutes;
175
185
  }
176
186
 
177
- export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing };
187
+ function wrapUseRoutes(origUseRoutes) {
188
+ if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) {
189
+ (typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
190
+ logger.warn(
191
+ 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.',
192
+ );
193
+
194
+ return origUseRoutes;
195
+ }
196
+
197
+ let isBaseLocation = false;
198
+
199
+ return (routes, location) => {
200
+ var SentryRoutes = (props) => {
201
+ var Routes = origUseRoutes(routes, location);
202
+
203
+ var locationArgObject = typeof location === 'string' ? { pathname: location } : location;
204
+ var locationObject = (locationArgObject ) || _useLocation();
205
+ var navigationType = _useNavigationType();
206
+
207
+ _useEffect(() => {
208
+ isBaseLocation = true;
209
+
210
+ updatePageloadTransaction(locationObject, routes);
211
+ }, [props]);
212
+
213
+ _useEffect(() => {
214
+ handleNavigation(locationObject, routes, navigationType, isBaseLocation);
215
+ }, [props, locationObject, navigationType, isBaseLocation]);
216
+
217
+ isBaseLocation = false;
218
+
219
+ return Routes;
220
+ };
221
+
222
+ return React__default.createElement(SentryRoutes, {__self: this, __source: {fileName: _jsxFileName, lineNumber: 268}} );
223
+ };
224
+ }
225
+
226
+ export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing, wrapUseRoutes };
178
227
  //# sourceMappingURL=reactrouterv6.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouterv6.js","sources":["../../src/reactrouterv6.tsx"],"sourcesContent":["// Inspired from Donnie McNeal's solution:\n// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536\n\nimport { Transaction, TransactionContext, TransactionSource } from '@sentry/types';\nimport { getGlobalObject, getNumberOfUrlSegments, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport React from 'react';\n\nimport { Action, Location } from './types';\n\ninterface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\ntype Params<Key extends string = string> = {\n readonly [key in Key]: string | undefined;\n};\n\n// https://github.com/remix-run/react-router/blob/9fa54d643134cd75a0335581a75db8100ed42828/packages/react-router/lib/router.ts#L114-L134\ninterface RouteMatch<ParamKey extends string = string> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params<ParamKey>;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObject;\n}\n\ntype UseEffect = (cb: () => void, deps: unknown[]) => void;\ntype UseLocation = () => Location;\ntype UseNavigationType = () => Action;\ntype CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject[];\ntype MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;\n\nlet activeTransaction: Transaction | undefined;\n\nlet _useEffect: UseEffect;\nlet _useLocation: UseLocation;\nlet _useNavigationType: UseNavigationType;\nlet _createRoutesFromChildren: CreateRoutesFromChildren;\nlet _matchRoutes: MatchRoutes;\nlet _customStartTransaction: (context: TransactionContext) => Transaction | undefined;\nlet _startTransactionOnLocationChange: boolean;\n\nconst global = getGlobalObject<Window>();\n\nconst SENTRY_TAGS = {\n 'routing.instrumentation': 'react-router-v6',\n};\n\nexport function reactRouterV6Instrumentation(\n useEffect: UseEffect,\n useLocation: UseLocation,\n useNavigationType: UseNavigationType,\n createRoutesFromChildren: CreateRoutesFromChildren,\n matchRoutes: MatchRoutes,\n) {\n return (\n customStartTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad = true,\n startTransactionOnLocationChange = true,\n ): void => {\n const initPathName = global && global.location && global.location.pathname;\n if (startTransactionOnPageLoad && initPathName) {\n activeTransaction = customStartTransaction({\n name: initPathName,\n op: 'pageload',\n tags: SENTRY_TAGS,\n metadata: {\n source: 'url',\n },\n });\n }\n\n _useEffect = useEffect;\n _useLocation = useLocation;\n _useNavigationType = useNavigationType;\n _matchRoutes = matchRoutes;\n _createRoutesFromChildren = createRoutesFromChildren;\n\n _customStartTransaction = customStartTransaction;\n _startTransactionOnLocationChange = startTransactionOnLocationChange;\n };\n}\n\nfunction getNormalizedName(\n routes: RouteObject[],\n location: Location,\n matchRoutes: MatchRoutes,\n): [string, TransactionSource] {\n if (!routes || routes.length === 0 || !matchRoutes) {\n return [location.pathname, 'url'];\n }\n\n const branches = matchRoutes(routes, location);\n\n let pathBuilder = '';\n if (branches) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n const branch = branches[x];\n const route = branch.route;\n if (route) {\n // Early return if index route\n if (route.index) {\n return [branch.pathname, 'route'];\n }\n\n const path = route.path;\n if (path) {\n const newPath = path[0] === '/' ? path : `/${path}`;\n pathBuilder += newPath;\n if (branch.pathname === location.pathname) {\n // If the route defined on the element is something like\n // <Route path=\"/stores/:storeId/products/:productId\" element={<div>Product</div>} />\n // We should check against the branch.pathname for the number of / seperators\n if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname)) {\n return [newPath, 'route'];\n }\n return [pathBuilder, 'route'];\n }\n }\n }\n }\n }\n\n return [location.pathname, 'url'];\n}\n\nexport function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R {\n if (\n !_useEffect ||\n !_useLocation ||\n !_useNavigationType ||\n !_createRoutesFromChildren ||\n !_matchRoutes ||\n !_customStartTransaction\n ) {\n __DEBUG_BUILD__ &&\n logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');\n\n return Routes;\n }\n\n let isBaseLocation: boolean = false;\n let routes: RouteObject[];\n\n const SentryRoutes: React.FC<P> = (props: P) => {\n const location = _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n // Performance concern:\n // This is repeated when <Routes /> is rendered.\n routes = _createRoutesFromChildren(props.children);\n isBaseLocation = true;\n\n if (activeTransaction) {\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction.setName(name);\n activeTransaction.setMetadata({ source });\n }\n\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.children]);\n\n _useEffect(() => {\n if (isBaseLocation) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n return;\n }\n\n if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction = _customStartTransaction({\n name,\n op: 'navigation',\n tags: SENTRY_TAGS,\n metadata: {\n source,\n },\n });\n }\n }, [props.children, location, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return <Routes {...props} />;\n };\n\n hoistNonReactStatics(SentryRoutes, Routes);\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return SentryRoutes;\n}\n"],"names":[],"mappings":";;;;AAAA;;AAgDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
1
+ {"version":3,"file":"reactrouterv6.js","sources":["../../src/reactrouterv6.tsx"],"sourcesContent":["// Inspired from Donnie McNeal's solution:\n// https://gist.github.com/wontondon/e8c4bdf2888875e4c755712e99279536\n\nimport { Transaction, TransactionContext, TransactionSource } from '@sentry/types';\nimport { getGlobalObject, getNumberOfUrlSegments, logger } from '@sentry/utils';\nimport hoistNonReactStatics from 'hoist-non-react-statics';\nimport React from 'react';\n\nimport { Action, Location } from './types';\n\ninterface RouteObject {\n caseSensitive?: boolean;\n children?: RouteObject[];\n element?: React.ReactNode;\n index?: boolean;\n path?: string;\n}\n\ntype Params<Key extends string = string> = {\n readonly [key in Key]: string | undefined;\n};\n\ntype UseRoutes = (routes: RouteObject[], locationArg?: Partial<Location> | string) => React.ReactElement | null;\n\n// https://github.com/remix-run/react-router/blob/9fa54d643134cd75a0335581a75db8100ed42828/packages/react-router/lib/router.ts#L114-L134\ninterface RouteMatch<ParamKey extends string = string> {\n /**\n * The names and values of dynamic parameters in the URL.\n */\n params: Params<ParamKey>;\n /**\n * The portion of the URL pathname that was matched.\n */\n pathname: string;\n /**\n * The portion of the URL pathname that was matched before child routes.\n */\n pathnameBase: string;\n /**\n * The route object that was used to match.\n */\n route: RouteObject;\n}\n\ntype UseEffect = (cb: () => void, deps: unknown[]) => void;\ntype UseLocation = () => Location;\ntype UseNavigationType = () => Action;\ntype CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject[];\ntype MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;\n\nlet activeTransaction: Transaction | undefined;\n\nlet _useEffect: UseEffect;\nlet _useLocation: UseLocation;\nlet _useNavigationType: UseNavigationType;\nlet _createRoutesFromChildren: CreateRoutesFromChildren;\nlet _matchRoutes: MatchRoutes;\nlet _customStartTransaction: (context: TransactionContext) => Transaction | undefined;\nlet _startTransactionOnLocationChange: boolean;\n\nconst global = getGlobalObject<Window>();\n\nconst SENTRY_TAGS = {\n 'routing.instrumentation': 'react-router-v6',\n};\n\nexport function reactRouterV6Instrumentation(\n useEffect: UseEffect,\n useLocation: UseLocation,\n useNavigationType: UseNavigationType,\n createRoutesFromChildren: CreateRoutesFromChildren,\n matchRoutes: MatchRoutes,\n) {\n return (\n customStartTransaction: (context: TransactionContext) => Transaction | undefined,\n startTransactionOnPageLoad = true,\n startTransactionOnLocationChange = true,\n ): void => {\n const initPathName = global && global.location && global.location.pathname;\n if (startTransactionOnPageLoad && initPathName) {\n activeTransaction = customStartTransaction({\n name: initPathName,\n op: 'pageload',\n tags: SENTRY_TAGS,\n metadata: {\n source: 'url',\n },\n });\n }\n\n _useEffect = useEffect;\n _useLocation = useLocation;\n _useNavigationType = useNavigationType;\n _matchRoutes = matchRoutes;\n _createRoutesFromChildren = createRoutesFromChildren;\n\n _customStartTransaction = customStartTransaction;\n _startTransactionOnLocationChange = startTransactionOnLocationChange;\n };\n}\n\nfunction getNormalizedName(\n routes: RouteObject[],\n location: Location,\n matchRoutes: MatchRoutes,\n): [string, TransactionSource] {\n if (!routes || routes.length === 0 || !matchRoutes) {\n return [location.pathname, 'url'];\n }\n\n const branches = matchRoutes(routes, location);\n\n let pathBuilder = '';\n if (branches) {\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let x = 0; x < branches.length; x++) {\n const branch = branches[x];\n const route = branch.route;\n if (route) {\n // Early return if index route\n if (route.index) {\n return [branch.pathname, 'route'];\n }\n\n const path = route.path;\n if (path) {\n const newPath = path[0] === '/' ? path : `/${path}`;\n pathBuilder += newPath;\n if (branch.pathname === location.pathname) {\n // If the route defined on the element is something like\n // <Route path=\"/stores/:storeId/products/:productId\" element={<div>Product</div>} />\n // We should check against the branch.pathname for the number of / seperators\n if (getNumberOfUrlSegments(pathBuilder) !== getNumberOfUrlSegments(branch.pathname)) {\n return [newPath, 'route'];\n }\n return [pathBuilder, 'route'];\n }\n }\n }\n }\n }\n\n return [location.pathname, 'url'];\n}\n\nfunction updatePageloadTransaction(location: Location, routes: RouteObject[]): void {\n if (activeTransaction) {\n activeTransaction.setName(...getNormalizedName(routes, location, _matchRoutes));\n }\n}\n\nfunction handleNavigation(\n location: Location,\n routes: RouteObject[],\n navigationType: Action,\n isBaseLocation: boolean,\n): void {\n if (isBaseLocation) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n return;\n }\n\n if (_startTransactionOnLocationChange && (navigationType === 'PUSH' || navigationType === 'POP')) {\n if (activeTransaction) {\n activeTransaction.finish();\n }\n\n const [name, source] = getNormalizedName(routes, location, _matchRoutes);\n activeTransaction = _customStartTransaction({\n name,\n op: 'navigation',\n tags: SENTRY_TAGS,\n metadata: {\n source,\n },\n });\n }\n}\n\nexport function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R {\n if (\n !_useEffect ||\n !_useLocation ||\n !_useNavigationType ||\n !_createRoutesFromChildren ||\n !_matchRoutes ||\n !_customStartTransaction\n ) {\n __DEBUG_BUILD__ &&\n logger.warn('reactRouterV6Instrumentation was unable to wrap Routes because of one or more missing parameters.');\n\n return Routes;\n }\n\n let isBaseLocation: boolean = false;\n let routes: RouteObject[];\n\n const SentryRoutes: React.FC<P> = (props: P) => {\n const location = _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n // Performance concern:\n // This is repeated when <Routes /> is rendered.\n routes = _createRoutesFromChildren(props.children);\n isBaseLocation = true;\n\n updatePageloadTransaction(location, routes);\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [props.children]);\n\n _useEffect(() => {\n handleNavigation(location, routes, navigationType, isBaseLocation);\n }, [props.children, location, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return <Routes {...props} />;\n };\n\n hoistNonReactStatics(SentryRoutes, Routes);\n\n // @ts-ignore Setting more specific React Component typing for `R` generic above\n // will break advanced type inference done by react router params\n return SentryRoutes;\n}\n\nexport function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes {\n if (!_useEffect || !_useLocation || !_useNavigationType || !_matchRoutes || !_customStartTransaction) {\n __DEBUG_BUILD__ &&\n logger.warn(\n 'reactRouterV6Instrumentation was unable to wrap `useRoutes` because of one or more missing parameters.',\n );\n\n return origUseRoutes;\n }\n\n let isBaseLocation: boolean = false;\n\n return (routes: RouteObject[], location?: Partial<Location> | string): React.ReactElement | null => {\n const SentryRoutes: React.FC<unknown> = (props: unknown) => {\n const Routes = origUseRoutes(routes, location);\n\n const locationArgObject = typeof location === 'string' ? { pathname: location } : location;\n const locationObject = (locationArgObject as Location) || _useLocation();\n const navigationType = _useNavigationType();\n\n _useEffect(() => {\n isBaseLocation = true;\n\n updatePageloadTransaction(locationObject, routes);\n }, [props]);\n\n _useEffect(() => {\n handleNavigation(locationObject, routes, navigationType, isBaseLocation);\n }, [props, locationObject, navigationType, isBaseLocation]);\n\n isBaseLocation = false;\n\n return Routes;\n };\n\n return <SentryRoutes />;\n };\n}\n"],"names":[],"mappings":";;;;AAAA;;AAkDA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sentry/react",
3
- "version": "7.12.0",
3
+ "version": "7.12.1",
4
4
  "description": "Official Sentry SDK for React.js",
5
5
  "repository": "git://github.com/getsentry/sentry-javascript.git",
6
6
  "homepage": "https://github.com/getsentry/sentry-javascript/tree/master/packages/react",
@@ -16,9 +16,9 @@
16
16
  "access": "public"
17
17
  },
18
18
  "dependencies": {
19
- "@sentry/browser": "7.12.0",
20
- "@sentry/types": "7.12.0",
21
- "@sentry/utils": "7.12.0",
19
+ "@sentry/browser": "7.12.1",
20
+ "@sentry/types": "7.12.1",
21
+ "@sentry/utils": "7.12.1",
22
22
  "hoist-non-react-statics": "^3.3.2",
23
23
  "tslib": "^1.9.3"
24
24
  },
package/types/index.d.ts CHANGED
@@ -6,5 +6,5 @@ export { ErrorBoundary, withErrorBoundary } from './errorboundary';
6
6
  export { createReduxEnhancer } from './redux';
7
7
  export { reactRouterV3Instrumentation } from './reactrouterv3';
8
8
  export { reactRouterV4Instrumentation, reactRouterV5Instrumentation, withSentryRouting } from './reactrouter';
9
- export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing } from './reactrouterv6';
9
+ export { reactRouterV6Instrumentation, withSentryReactRouterV6Routing, wrapUseRoutes } from './reactrouterv6';
10
10
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,MAAM,iBAAiB,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,iBAAiB,CAAC;AAEhC,OAAO,EAAE,IAAI,EAAE,MAAM,OAAO,CAAC;AAC7B,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AACjE,YAAY,EAAE,kBAAkB,EAAE,cAAc,EAAE,MAAM,iBAAiB,CAAC;AAC1E,OAAO,EAAE,aAAa,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;AACnE,OAAO,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAC;AAC9C,OAAO,EAAE,4BAA4B,EAAE,MAAM,iBAAiB,CAAC;AAC/D,OAAO,EAAE,4BAA4B,EAAE,4BAA4B,EAAE,iBAAiB,EAAE,MAAM,eAAe,CAAC;AAC9G,OAAO,EAAE,4BAA4B,EAAE,8BAA8B,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouter.d.ts","sourceRoot":"","sources":["../../src/reactrouter.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAKvE,aAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,oBAAY,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;CACjE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAExB,oBAAY,WAAW,GAAG;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF,aAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC;AAO3G,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,EACtB,MAAM,CAAC,EAAE,WAAW,EAAE,EACtB,SAAS,CAAC,EAAE,SAAS,GACpB,0BAA0B,CAE5B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,EACtB,MAAM,CAAC,EAAE,WAAW,EAAE,EACtB,SAAS,CAAC,EAAE,SAAS,GACpB,0BAA0B,CAE5B;AAsHD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAqB9G"}
1
+ {"version":3,"file":"reactrouter.d.ts","sourceRoot":"","sources":["../../src/reactrouter.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAE/B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAC;AAKvE,aAAK,KAAK,GAAG;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE,CAAC;AAE1F,oBAAY,aAAa,GAAG;IAC1B,QAAQ,CAAC,EAAE,QAAQ,CAAC;IACpB,MAAM,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,KAAK,IAAI,GAAG,IAAI,CAAC;CACjE,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAExB,oBAAY,WAAW,GAAG;IACxB,CAAC,QAAQ,EAAE,MAAM,GAAG,GAAG,CAAC;IACxB,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IACzB,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,SAAS,CAAC,EAAE,GAAG,CAAC,OAAO,CAAC;IACxB,MAAM,CAAC,EAAE,WAAW,EAAE,CAAC;CACxB,CAAC;AAEF,aAAK,SAAS,GAAG,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,EAAE,GAAG,GAAG,EAAE,MAAM,CAAC,EAAE,KAAK,GAAG,IAAI,KAAK,KAAK,GAAG,IAAI,CAAC;AAO3G,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,EACtB,MAAM,CAAC,EAAE,WAAW,EAAE,EACtB,SAAS,CAAC,EAAE,SAAS,GACpB,0BAA0B,CAE5B;AAED,wBAAgB,4BAA4B,CAC1C,OAAO,EAAE,aAAa,EACtB,MAAM,CAAC,EAAE,WAAW,EAAE,EACtB,SAAS,CAAC,EAAE,SAAS,GACpB,0BAA0B,CAE5B;AAsHD,wBAAgB,iBAAiB,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,CAAC,CAoB9G"}
@@ -11,6 +11,7 @@ interface RouteObject {
11
11
  declare type Params<Key extends string = string> = {
12
12
  readonly [key in Key]: string | undefined;
13
13
  };
14
+ declare type UseRoutes = (routes: RouteObject[], locationArg?: Partial<Location> | string) => React.ReactElement | null;
14
15
  interface RouteMatch<ParamKey extends string = string> {
15
16
  /**
16
17
  * The names and values of dynamic parameters in the URL.
@@ -36,5 +37,6 @@ declare type CreateRoutesFromChildren = (children: JSX.Element[]) => RouteObject
36
37
  declare type MatchRoutes = (routes: RouteObject[], location: Location) => RouteMatch[] | null;
37
38
  export declare function reactRouterV6Instrumentation(useEffect: UseEffect, useLocation: UseLocation, useNavigationType: UseNavigationType, createRoutesFromChildren: CreateRoutesFromChildren, matchRoutes: MatchRoutes): (customStartTransaction: (context: TransactionContext) => Transaction | undefined, startTransactionOnPageLoad?: boolean, startTransactionOnLocationChange?: boolean) => void;
38
39
  export declare function withSentryReactRouterV6Routing<P extends Record<string, any>, R extends React.FC<P>>(Routes: R): R;
40
+ export declare function wrapUseRoutes(origUseRoutes: UseRoutes): UseRoutes;
39
41
  export {};
40
42
  //# sourceMappingURL=reactrouterv6.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"reactrouterv6.d.ts","sourceRoot":"","sources":["../../src/reactrouterv6.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AAGnF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE3C,UAAU,WAAW;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,aAAK,MAAM,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IACzC,QAAQ,EAAE,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,SAAS;CAC1C,CAAC;AAGF,UAAU,UAAU,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IACnD;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,aAAK,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAC3D,aAAK,WAAW,GAAG,MAAM,QAAQ,CAAC;AAClC,aAAK,iBAAiB,GAAG,MAAM,MAAM,CAAC;AACtC,aAAK,wBAAwB,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,WAAW,EAAE,CAAC;AAC3E,aAAK,WAAW,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,KAAK,UAAU,EAAE,GAAG,IAAI,CAAC;AAkBtF,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,iBAAiB,EACpC,wBAAwB,EAAE,wBAAwB,EAClD,WAAW,EAAE,WAAW,gLA4BzB;AA8CD,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CA2EjH"}
1
+ {"version":3,"file":"reactrouterv6.d.ts","sourceRoot":"","sources":["../../src/reactrouterv6.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAE,WAAW,EAAE,kBAAkB,EAAqB,MAAM,eAAe,CAAC;AAGnF,OAAO,KAAK,MAAM,OAAO,CAAC;AAE1B,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAE3C,UAAU,WAAW;IACnB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,QAAQ,CAAC,EAAE,WAAW,EAAE,CAAC;IACzB,OAAO,CAAC,EAAE,KAAK,CAAC,SAAS,CAAC;IAC1B,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED,aAAK,MAAM,CAAC,GAAG,SAAS,MAAM,GAAG,MAAM,IAAI;IACzC,QAAQ,EAAE,GAAG,IAAI,GAAG,GAAG,MAAM,GAAG,SAAS;CAC1C,CAAC;AAEF,aAAK,SAAS,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,WAAW,CAAC,EAAE,OAAO,CAAC,QAAQ,CAAC,GAAG,MAAM,KAAK,KAAK,CAAC,YAAY,GAAG,IAAI,CAAC;AAGhH,UAAU,UAAU,CAAC,QAAQ,SAAS,MAAM,GAAG,MAAM;IACnD;;OAEG;IACH,MAAM,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAC;IACzB;;OAEG;IACH,QAAQ,EAAE,MAAM,CAAC;IACjB;;OAEG;IACH,YAAY,EAAE,MAAM,CAAC;IACrB;;OAEG;IACH,KAAK,EAAE,WAAW,CAAC;CACpB;AAED,aAAK,SAAS,GAAG,CAAC,EAAE,EAAE,MAAM,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,IAAI,CAAC;AAC3D,aAAK,WAAW,GAAG,MAAM,QAAQ,CAAC;AAClC,aAAK,iBAAiB,GAAG,MAAM,MAAM,CAAC;AACtC,aAAK,wBAAwB,GAAG,CAAC,QAAQ,EAAE,GAAG,CAAC,OAAO,EAAE,KAAK,WAAW,EAAE,CAAC;AAC3E,aAAK,WAAW,GAAG,CAAC,MAAM,EAAE,WAAW,EAAE,EAAE,QAAQ,EAAE,QAAQ,KAAK,UAAU,EAAE,GAAG,IAAI,CAAC;AAkBtF,wBAAgB,4BAA4B,CAC1C,SAAS,EAAE,SAAS,EACpB,WAAW,EAAE,WAAW,EACxB,iBAAiB,EAAE,iBAAiB,EACpC,wBAAwB,EAAE,wBAAwB,EAClD,WAAW,EAAE,WAAW,gLA4BzB;AAmFD,wBAAgB,8BAA8B,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,CAAC,SAAS,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,CAgDjH;AAED,wBAAgB,aAAa,CAAC,aAAa,EAAE,SAAS,GAAG,SAAS,CAqCjE"}