import { Router, NavigationFailure, RouteLocationOptions } from 'vue-router' import { RoutiderOptions, RouteNames, RoutiderRoutes, FlatRoutes } from '../options/options' import { RouteQueryAndHash } from '../vue-router-utils' import { ExtractParams } from '../options/path' import { RoutiderRouteRecord } from '../route/route' import { RoutiderNavigationGuardWithThis, RoutiderPostNavigationGuard } from './navigationGuard' import { RoutiderLocation, RoutiderLocationOfNames } from '../route/location' type ParamsOfRouteName = ExtractParams< Route['path'] > type ParamsObjOfRouteName< Route extends RoutiderRouteRecord > = ParamsOfRouteName extends never // eslint-disable-next-line @typescript-eslint/ban-types ? {} : { params: Record, string> } export type RoutiderRouteLocation< Routes extends RoutiderRoutes, N extends keyof Routes > = RouteQueryAndHash & { name: N } & ParamsObjOfRouteName & RouteLocationOptions export interface RoutiderRouter extends Router { addRoute: never removeRoute: never push>>( to: RoutiderRouteLocation, N> ): Promise replace>>( to: RoutiderRouteLocation, N> ): Promise beforeEach( guard: RoutiderNavigationGuardWithThis> ): () => void beforeResolve( guard: RoutiderNavigationGuardWithThis> ): () => void afterEach( guard: RoutiderPostNavigationGuard> ): () => void isRouteName>>( location: RoutiderLocation< undefined, undefined, undefined, RouteNames> >, name: N ): location is RoutiderLocationOfNames< FlatRoutes, Exclude > getOptionalTypedRoute( location: RoutiderLocation< undefined, undefined, undefined, RouteNames> > ): RoutiderLocationOfNames< FlatRoutes, RouteNames> > } export const createRoutiderRouter = ( router: Router ): RoutiderRouter => { const isRouteName = >>( location: RoutiderLocation< undefined, undefined, undefined, RouteNames> >, name: N ): location is RoutiderLocationOfNames< FlatRoutes, Exclude > => name === location.name const getOptionalTypedRoute = ( location: RoutiderLocation< undefined, undefined, undefined, RouteNames> > ) => location as RoutiderLocationOfNames< FlatRoutes, RouteNames> > return { ...router, isRouteName, getOptionalTypedRoute } as RoutiderRouter }