import { useRouter } from 'next/compat/router'; import { createContext, PropsWithChildren, useCallback, useContext } from 'react'; import { isVersionedPath } from '~/common/routes'; import navigation from '~/public/static/constants/navigation.json'; export const PageApiVersionContext = createContext({ /** The version selected in the URL, or the default version */ version: 'latest', /** If the current URL has a version defined */ hasVersion: false, /** Change the URL to the select version */ setVersion: newVersion => { throw new Error('PageApiVersionContext not found'); }, } as PageApiVersionContextType); export type PageApiVersionContextType = { version: keyof typeof navigation.reference; hasVersion: boolean; setVersion: (newVersion: string) => void; }; type Props = PropsWithChildren; export function PageApiVersionProvider({ children }: Props) { const router = useRouter(); const version = getVersionFromPath(router?.pathname ?? ''); const hasVersion = version !== null; // note(Cedric): if the page doesn't exists, the error page will handle it const setVersion = useCallback((newVersion: string) => { router?.push(replaceVersionInPath(router.pathname, newVersion)); }, []); return ( {children} ); } export function usePageApiVersion() { return useContext(PageApiVersionContext); } /** * Find the version within the pathname of the URL. * This only accepts pathname without hashes or query strings. */ export function getVersionFromPath(path: string): PageApiVersionContextType['version'] | null { return isVersionedPath(path) ? (path.split('/', 3).pop()! as PageApiVersionContextType['version']) : null; } /** * Replace the version in the pathname from the URL. * If no version was found, the path is returned as is. */ export function replaceVersionInPath(path: string, newVersion: string) { const version = getVersionFromPath(path); return version ? path.replace(version, newVersion) : path; }