{"version":3,"sources":["../src/router/router.ts","../src/router/react.tsx"],"sourcesContent":["import type { ClerkHostRouter, RoutingMode } from '@clerk/types';\n\nimport { isAbsoluteUrl, withLeadingSlash, withoutTrailingSlash } from '../url';\n\nexport const PRESERVED_QUERYSTRING_PARAMS = ['after_sign_in_url', 'after_sign_up_url', 'redirect_url'];\n\n/**\n * Internal Clerk router, used by Clerk components to interact with the host's router.\n */\nexport type ClerkRouter = {\n  makeDestinationUrlWithPreservedQueryParameters: (path: string) => string;\n  /**\n   * The basePath the router is currently mounted on.\n   */\n  basePath: string;\n  /**\n   * Creates a child router instance scoped to the provided base path.\n   */\n  child: (childBasePath: string) => ClerkRouter;\n  /**\n   * Matches the provided path against the router's current path. If index is provided, matches against the root route of the router.\n   */\n  match: (path?: string, index?: boolean) => boolean;\n\n  /**\n   * Mode of the router instance, path-based or virtual\n   */\n  readonly mode: RoutingMode;\n\n  /**\n   * Name of the router instance\n   */\n  readonly name: string;\n\n  /**\n   * Navigates to the provided path via a history push\n   */\n  push: ClerkHostRouter['push'];\n  /**\n   * Navigates to the provided path via a history replace\n   */\n  replace: ClerkHostRouter['replace'];\n  /**\n   * If supported by the host router, navigates to the provided path without triggering a full navigation\n   */\n  shallowPush: ClerkHostRouter['shallowPush'];\n  /**\n   * Returns the current pathname (including the base path)\n   */\n  pathname: ClerkHostRouter['pathname'];\n  /**\n   * Returns the current search params\n   */\n  searchParams: ClerkHostRouter['searchParams'];\n};\n\n/**\n * Ensures the provided path has a leading slash and no trailing slash\n */\nfunction normalizePath(path: string) {\n  return withoutTrailingSlash(withLeadingSlash(path));\n}\n\n/**\n * Factory function to create an instance of ClerkRouter with the provided host router.\n *\n * @param router host router instance to be used by the router\n * @param basePath base path of the router, navigation and matching will be scoped to this path\n * @returns A ClerkRouter instance\n */\nexport function createClerkRouter(router: ClerkHostRouter, basePath: string = '/'): ClerkRouter {\n  const normalizedBasePath = normalizePath(basePath);\n\n  /**\n   * Certain query parameters need to be preserved when navigating internally. These query parameters are ultimately used by Clerk to dictate behavior, so we keep them around.\n   */\n  function makeDestinationUrlWithPreservedQueryParameters(path: string) {\n    // If the provided path is an absolute URL, return it unmodified.\n    if (isAbsoluteUrl(path)) {\n      return path;\n    }\n\n    const destinationUrl = new URL(path, window.location.origin);\n    const currentSearchParams = router.searchParams();\n\n    PRESERVED_QUERYSTRING_PARAMS.forEach(key => {\n      const maybeValue = currentSearchParams.get(key);\n      if (maybeValue) {\n        destinationUrl.searchParams.set(key, maybeValue);\n      }\n    });\n\n    return `${destinationUrl.pathname}${destinationUrl.search}`;\n  }\n\n  function match(path?: string, index?: boolean) {\n    const pathToMatch = path ?? (index && '/');\n\n    if (!pathToMatch) {\n      throw new Error('[clerk] router.match() requires either a path to match, or the index flag must be set to true.');\n    }\n\n    const normalizedPath = normalizePath(pathToMatch);\n\n    return normalizePath(`${normalizedBasePath}${normalizedPath}`) === normalizePath(router.pathname());\n  }\n\n  function child(childBasePath: string) {\n    return createClerkRouter(router, `${normalizedBasePath}${normalizePath(childBasePath)}`);\n  }\n\n  function push(path: string) {\n    const destinationUrl = makeDestinationUrlWithPreservedQueryParameters(path);\n    return router.push(destinationUrl);\n  }\n\n  function replace(path: string) {\n    const destinationUrl = makeDestinationUrlWithPreservedQueryParameters(path);\n    return router.replace(destinationUrl);\n  }\n\n  function shallowPush(path: string) {\n    const destinationUrl = makeDestinationUrlWithPreservedQueryParameters(path);\n    return router.shallowPush(destinationUrl);\n  }\n\n  function pathname() {\n    return router.pathname();\n  }\n\n  function searchParams() {\n    return router.searchParams();\n  }\n\n  return {\n    makeDestinationUrlWithPreservedQueryParameters,\n    child,\n    match,\n    mode: router.mode,\n    name: router.name,\n    push,\n    replace,\n    shallowPush,\n    pathname,\n    searchParams,\n    basePath: normalizedBasePath,\n  };\n}\n\nexport type { ClerkHostRouter, RoutingMode };\n","/**\n * React-specific binding's for interacting with Clerk's router interface.\n */\nimport React, { createContext, useContext } from 'react';\n\nimport type { ClerkHostRouter, ClerkRouter } from './router';\nimport { createClerkRouter } from './router';\n\nexport const ClerkHostRouterContext = createContext<ClerkHostRouter | null>(null);\nexport const ClerkRouterContext = createContext<ClerkRouter | null>(null);\n\nexport function useClerkHostRouter() {\n  const ctx = useContext(ClerkHostRouterContext);\n\n  if (!ctx) {\n    throw new Error(\n      'clerk: Unable to locate ClerkHostRouter, make sure this is rendered within `<ClerkHostRouterContext.Provider>`.',\n    );\n  }\n\n  return ctx;\n}\n\nexport function useClerkRouter() {\n  const ctx = useContext(ClerkRouterContext);\n\n  if (!ctx) {\n    throw new Error('clerk: Unable to locate ClerkRouter, make sure this is rendered within `<Router>`.');\n  }\n\n  return ctx;\n}\n\n/**\n * Construct a Clerk Router using the provided host router. The router instance is accessible using `useClerkRouter()`.\n */\nexport function Router({\n  basePath,\n  children,\n  router,\n}: {\n  children: React.ReactNode;\n  basePath?: string;\n  router?: ClerkHostRouter;\n}) {\n  const hostRouter = useClerkHostRouter();\n  const clerkRouter = createClerkRouter(router ?? hostRouter, basePath);\n\n  return <ClerkRouterContext.Provider value={clerkRouter}>{children}</ClerkRouterContext.Provider>;\n}\n\ntype RouteProps = { path?: string; index?: boolean };\n\n/**\n * Used to conditionally render its children based on whether or not the current path matches the provided path.\n */\nexport function Route({ path, children, index }: RouteProps & { children: React.ReactNode }) {\n  const parentRouter = useClerkRouter();\n\n  if (!path && !index) {\n    return children;\n  }\n\n  if (!parentRouter?.match(path, index)) {\n    return null;\n  }\n\n  return children;\n}\n"],"mappings":"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","names":[]}