import { RouterOptions, RouteRecordRaw } from 'vue-router' import { RouteRecordName } from './name' import { RoutiderRouteRecord, pathToPathAndAlias, ExtractChildren } from '../route/route' import { UnionToIntersection } from '../type' import { Path, pathsToString, pathToString, ExtractParams } from './path' import warning from 'tiny-warning' import { ExtractQueries } from './queries' export type RoutiderRoutes = Record export interface RoutiderOptions extends Omit { routes: RoutiderRoutes } export type RouteNames = Routes extends Record< infer K, unknown > ? K : never type AddParentParams< ParentPath extends Path, Children extends RoutiderRoutes > = { [K in keyof Children]: RoutiderRouteRecord< ExtractParams | ExtractParams, ExtractQueries, ExtractChildren > } type ExtractChildrenWithParentParams< T extends RoutiderRouteRecord > = ExtractChildren extends RoutiderRoutes ? AddParentParams> : never export type FlatRoutes = T & UnionToIntersection< { [K in keyof T]: FlatRoutes> }[keyof T] > export const warnIfNonTopLevelAbsolutePath = (path: Path): void => { const warnText = 'Absolute paths cannot be used with Vue Routider.' if (Array.isArray(path)) { warning( !pathsToString(path).some(p => p.startsWith('/')), `${warnText} (${path.join(', ')})` ) } else { warning(!pathToString(path).startsWith('/'), `${warnText} (${path})`) } } export const routiderRoutesToRouteRecords = ( routes: RoutiderRoutes, isTopLevel = true ): RouteRecordRaw[] => Object.entries(routes).map(([name, route]) => { if (__DEV__ && !isTopLevel) { warnIfNonTopLevelAbsolutePath(route.path) } return { ...route, name, ...pathToPathAndAlias(route.path), children: route.children ? routiderRoutesToRouteRecords(route.children, false) : undefined } as RouteRecordRaw }) export const routiderOptionsToRouterOptions = ( options: RoutiderOptions ): RouterOptions => ({ ...options, routes: routiderRoutesToRouteRecords(options.routes) })