From 18e131e62b9749083ef4a6509004a078283139f4 Mon Sep 17 00:00:00 2001 From: Orta Therox Date: Fri, 28 Jul 2023 10:18:24 +0100 Subject: [PATCH] Remove the indexed type reference on AvailableRoutes (#8918) Co-authored-by: Daniel Choudhury --- packages/router/src/AuthenticatedRoute.tsx | 20 +++++++++++++++----- packages/router/src/index.ts | 10 +++------- packages/router/src/util.ts | 14 ++++++++++---- 3 files changed, 28 insertions(+), 16 deletions(-) diff --git a/packages/router/src/AuthenticatedRoute.tsx b/packages/router/src/AuthenticatedRoute.tsx index 0a7a6941e2e0..dbac615d2446 100644 --- a/packages/router/src/AuthenticatedRoute.tsx +++ b/packages/router/src/AuthenticatedRoute.tsx @@ -3,10 +3,19 @@ import React, { useCallback } from 'react' import { Redirect } from './links' import { routes } from './router' import { useRouterState } from './router-context' +import type { GeneratedRoutesMap } from './util' -export function AuthenticatedRoute(props: any) { +interface AuthenticatedRouteProps { + children: React.ReactNode + roles?: string | string[] + unauthenticated?: keyof GeneratedRoutesMap + whileLoadingAuth?: () => React.ReactElement | null + private?: boolean +} + +export function AuthenticatedRoute(props: AuthenticatedRouteProps) { const { - private: privateSet, + private: isPrivate, unauthenticated, roles, whileLoadingAuth, @@ -24,7 +33,7 @@ export function AuthenticatedRoute(props: any) { }, [isAuthenticated, roles, hasRole]) // Make sure `wrappers` is always an array with at least one wrapper component - if (privateSet && unauthorized()) { + if (isPrivate && unauthorized()) { if (!unauthenticated) { throw new Error( 'Private Sets need to specify what route to redirect unauthorized ' + @@ -39,14 +48,15 @@ export function AuthenticatedRoute(props: any) { globalThis.location.pathname + encodeURIComponent(globalThis.location.search) - if (!routes[unauthenticated]) { + // We reassign the type like this, because AvailableRoutes is generated in the user's project + if (!(routes as GeneratedRoutesMap)[unauthenticated]) { throw new Error(`We could not find a route named ${unauthenticated}`) } let unauthenticatedPath try { - unauthenticatedPath = routes[unauthenticated]() + unauthenticatedPath = (routes as GeneratedRoutesMap)[unauthenticated]() } catch (e) { if ( e instanceof Error && diff --git a/packages/router/src/index.ts b/packages/router/src/index.ts index 83bbdc26dff7..7f879cf6b21c 100644 --- a/packages/router/src/index.ts +++ b/packages/router/src/index.ts @@ -22,8 +22,8 @@ export * from './route-focus' export { parseSearch, getRouteRegexAndParams, matchPath } from './util' /** - * A more specific interface will be generated by - * babel-plugin-redwood-routes-auto-loader when a redwood project is built + * A more specific interface is created in `.redwood/types/includes/web-routerRoutes` + * when the site is built, which will describe all known routes. * * @example * interface AvailableRoutes { @@ -32,11 +32,7 @@ export { parseSearch, getRouteRegexAndParams, matchPath } from './util' * } */ // Keep this in index.ts so it can be extended with declaration merging -export interface AvailableRoutes { - [key: string]: ( - args?: Record - ) => string -} +export interface AvailableRoutes {} export { SkipNavLink, SkipNavContent } from '@reach/skip-nav' diff --git a/packages/router/src/util.ts b/packages/router/src/util.ts index 8631d55febea..32081ec7c4b2 100644 --- a/packages/router/src/util.ts +++ b/packages/router/src/util.ts @@ -9,8 +9,6 @@ import { import { PageType } from './router' import { isPrivateNode, isSetNode } from './Set' -import { AvailableRoutes } from './' - /** Create a React Context with the given name. */ export function createNamedContext(name: string, defaultValue?: T) { const Ctx = React.createContext(defaultValue) @@ -445,6 +443,14 @@ interface AnayzeRoutesOptions { type WhileLoadingPage = () => ReactElement | null +// Not using AvailableRoutes because the type is generated in the user's project +// We can't index it correctly in the framework +export type GeneratedRoutesMap = { + [key: string]: ( + args?: Record + ) => string +} + type RoutePath = string interface AnalyzedRoute { path: RoutePath @@ -462,7 +468,7 @@ export function analyzeRoutes( { currentPathName, userParamTypes }: AnayzeRoutesOptions ) { const pathRouteMap: Record = {} - const namedRoutesMap: AvailableRoutes = {} + const namedRoutesMap: GeneratedRoutesMap = {} let hasHomeRoute = false let NotFoundPage: PageType | undefined let activeRoutePath: string | undefined @@ -478,7 +484,7 @@ export function analyzeRoutes( // Track the number of sets found. // Because Sets are virtually rendered we can use this setId as a key to properly manage re-rendering - // When a some uses the same wrapper Component for different Sets + // When using the same wrapper Component for different Sets // Example: // //