import * as path from "path" ; /**
 * A route that was created using `defineRoutes` or created conventionally from
 * looking at the files on the filesystem.
 */ export interface ConfigRoute { /**
     * The path this route uses to match on the URL pathname.
     */ path ? : string ; /**
     * Should be `true` if it is an index route. This disallows child routes.
     */ index ? : boolean ; /**
     * Should be `true` if the `path` is case-sensitive. Defaults to `false`.
     */ caseSensitive ? : boolean ; /**
     * The unique id for this route, named like its `file` but without the
     * extension. So `app/routes/gists/$username.jsx` will have an `id` of
     * `routes/gists/$username`.
     */ id : string ; /**
     * The unique `id` for this route's parent route, if there is one.
     */ parentId ? : string ; /**
     * The path to the entry point for this route, relative to
     * `config.appDirectory`.
     */ file : string ; } export interface RouteManifest { [ routeId ] : ConfigRoute ; } export interface DefineRouteOptions { /**
     * Should be `true` if the route `path` is case-sensitive. Defaults to
     * `false`.
     */ caseSensitive ? : boolean ; /**
     * Should be `true` if this is an index route that does not allow child routes.
     */ index ? : boolean ; } interface DefineRouteChildren { ( ) : void ; } /**
 * A function for defining a route that is passed as the argument to the
 * `defineRoutes` callback.
 *
 * Calls to this function are designed to be nested, using the `children`
 * callback argument.
 *
 *   defineRoutes(route => {
 *     route('/', 'pages/layout', () => {
 *       route('react-router', 'pages/react-router');
 *       route('reach-ui', 'pages/reach-ui');
 *     });
 *   });
 */ export interface DefineRouteFunction { ( /**
     * The path this route uses to match the URL pathname.
     */ path , /**
     * The path to the file that exports the React component rendered by this
     * route as its default export, relative to the `app` directory.
     */ file , /**
     * Options for defining routes, or a function for defining child routes.
     */ optionsOrChildren ? , /**
     * A function for defining child routes.
     */ children ? ) : void ; } export type DefineRoutesFunction = typeof defineRoutes ; /**
 * A function for defining routes programmatically, instead of using the
 * filesystem convention.
 */ export function defineRoutes ( callback ) { let routes = Object . create ( null ) ; let parentRoutes = [ ] ; let alreadyReturned = false ; let defineRoute = ( path , file , optionsOrChildren , children ) => { if ( alreadyReturned ) { throw new Error ( "You tried to define routes asynchronously but started defining " + "routes before the async work was done. Please await all async " + "data before calling `defineRoutes()`" ) ; } let options ; if ( typeof optionsOrChildren === "function" ) { options = { } ; children = optionsOrChildren ; } else { options = optionsOrChildren || { } ; } let route = { path : path ? path : undefined , index : options . index ? true : undefined , caseSensitive : options . caseSensitive ? true : undefined , id : createRouteId ( file ) , parentId : parentRoutes . length > 0 ? parentRoutes [ parentRoutes . length - 1 ] . id : undefined , file } ; routes [ route . id ] = route ; if ( children ) { parentRoutes . push ( route ) ; children ( ) ; parentRoutes . pop ( ) ; } } ; callback ( defineRoute ) ; alreadyReturned = true ; return routes ; } export function createRouteId ( file ) { return normalizeSlashes ( stripFileExtension ( file ) ) ; } export function normalizeSlashes ( file ) { return file . split ( path . win32 . sep ) . join ( "/" ) ; } function stripFileExtension ( file ) { return file . replace ( /\.[a-z0-9]+$/i , "" ) ; }