{"version":3,"file":"withEmbraceRouting.cjs","names":[],"sources":["../../../../../../src/instrumentations/navigation/NavigationInstrumentation/react/reactRouterV6Declarative/withEmbraceRouting.ts"],"sourcesContent":["import hoistNonReactStatics from 'hoist-non-react-statics';\nimport type React from 'react';\nimport { createElement } from 'react';\nimport type { Route } from '../../../../../api-page/index.ts';\nimport { page } from '../../../../../api-page/index.ts';\nimport type { RoutesFunctionalComponentReturn } from './types.ts';\n\n// Routes can be nested, we need to traverse the routeContext to find the last route\nconst getLastRoute = (\n  matchedComponent: RoutesFunctionalComponentReturn,\n  lastRoute: Route | null,\n): Route | null => {\n  if (!matchedComponent.props.match?.route) {\n    return null;\n  }\n\n  const childPath = matchedComponent.props.match.route.path;\n  const path =\n    lastRoute && !childPath.startsWith('/')\n      ? `${lastRoute.path}/${childPath}`\n      : childPath;\n\n  if (matchedComponent.props.routeContext?.outlet) {\n    return getLastRoute(matchedComponent.props.routeContext.outlet, {\n      path,\n      url: matchedComponent.props.match.pathname,\n    });\n  }\n\n  return {\n    path,\n    url: matchedComponent.props.match.pathname,\n  };\n};\n\nexport const withEmbraceRouting = <P extends object>(\n  WrappedComponent: React.FunctionComponent<P>,\n) => {\n  const RoutesWithEmbraceRouting: React.FC<P> = (props: P) => {\n    /**\n     * React-router v6+ implementation is very different from v5\n     * It doesn't have a <Switch> component that injects props into <Route>\n     * Instead, it has <Routes> which internally calculates the matched route\n     * and returns it as a children, <Route> cannot be wrapped since it requires all children to be a <Route> component\n     * here we rely on that matching to get the current route.\n     * It's not ideal to rely on internal implementation details, but it's the easier way of getting the current route\n     * without having to manually match it or using hooks on each children component\n     *\n     * See: https://github.com/remix-run/react-router/blob/main/packages/react-router/lib/hooks.tsx#L553\n     */\n    const matchedComponent = WrappedComponent(\n      props,\n    ) as unknown as RoutesFunctionalComponentReturn;\n\n    if (matchedComponent.props.match?.route) {\n      const lastRoute = getLastRoute(matchedComponent, null);\n      if (lastRoute) {\n        page.setCurrentRoute(lastRoute);\n      }\n    }\n\n    return createElement<P>(WrappedComponent, props);\n  };\n\n  // Keep wrapped component metadata\n  RoutesWithEmbraceRouting.displayName = `withEmbraceRouting(${WrappedComponent.displayName || WrappedComponent.name || 'Component'})`;\n  hoistNonReactStatics(RoutesWithEmbraceRouting, WrappedComponent);\n\n  return RoutesWithEmbraceRouting;\n};\n"],"mappings":";;;;;;;AAQA,MAAM,gBACJ,kBACA,cACiB;CACjB,IAAI,CAAC,iBAAiB,MAAM,OAAO,OACjC,OAAO;CAGT,MAAM,YAAY,iBAAiB,MAAM,MAAM,MAAM;CACrD,MAAM,OACJ,aAAa,CAAC,UAAU,WAAW,GAAG,IAClC,GAAG,UAAU,KAAK,GAAG,cACrB;CAEN,IAAI,iBAAiB,MAAM,cAAc,QACvC,OAAO,aAAa,iBAAiB,MAAM,aAAa,QAAQ;EAC9D;EACA,KAAK,iBAAiB,MAAM,MAAM;CACpC,CAAC;CAGH,OAAO;EACL;EACA,KAAK,iBAAiB,MAAM,MAAM;CACpC;AACF;AAEA,MAAa,sBACX,qBACG;CACH,MAAM,4BAAyC,UAAa;;;;;;;;;;;;EAY1D,MAAM,mBAAmB,iBACvB,KACF;EAEA,IAAI,iBAAiB,MAAM,OAAO,OAAO;GACvC,MAAM,YAAY,aAAa,kBAAkB,IAAI;GACrD,IAAI,WACF,yBAAA,KAAK,gBAAgB,SAAS;EAElC;EAEA,QAAA,GAAA,MAAA,cAAA,CAAwB,kBAAkB,KAAK;CACjD;CAGA,yBAAyB,cAAc,sBAAsB,iBAAiB,eAAe,iBAAiB,QAAQ,YAAY;CAClI,CAAA,GAAA,wBAAA,QAAA,CAAqB,0BAA0B,gBAAgB;CAE/D,OAAO;AACT"}