Skip to content

Commit

Permalink
improved implementation of createRouteMethods
Browse files Browse the repository at this point in the history
  • Loading branch information
stackoverfloweth committed Dec 27, 2023
1 parent cbbf863 commit 4869821
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 23 deletions.
12 changes: 9 additions & 3 deletions src/utilities/createRouteMethods.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,10 +62,14 @@ describe('createRouteMethods', () => {

const response = createRouteMethods(resolved)

expect(response.child).not.toBeUndefined()
expect(response.parent.child).not.toBeUndefined()

if (isPublic !== false) {
expect(response.parent.child).toBeTypeOf('function')
}
})

test.only('given parent route with named children and grandchildren, has path to grandchild', () => {
test('given parent route with named children and grandchildren, has path to grandchild all callable', () => {
const routes = [
{
name: 'parent',
Expand All @@ -89,6 +93,8 @@ describe('createRouteMethods', () => {

const response = createRouteMethods(resolved)

expect(response.child.grandchild).not.toBeUndefined()
expect(response.parent).toBeTypeOf('function')
expect(response.parent.child).toBeTypeOf('function')
expect(response.parent.child.grandchild).toBeTypeOf('function')
})
})
62 changes: 42 additions & 20 deletions src/utilities/createRouteMethods.ts
Original file line number Diff line number Diff line change
@@ -1,33 +1,55 @@
import { Resolved, Route, isPublicRoute } from '@/types'
import { Resolved, Route, RouteMethodRoute, isPublicRoute } from '@/types'
import { assembleUrl } from '@/utilities/urlAssembly'

export function createRouteMethods(routes: Resolved<Route>[]): Record<string, any> {
return routes.reduce<Record<string, any>>((methods, route) => {
const thing = assembleRouteParentContext(route, [...route.parentNames])
type NonCallableNode = Record<string, any>
type CallableNode = NonCallableNode & {
(values: Record<string, unknown[]>): RouteMethodRoute,
}
type Node = CallableNode | NonCallableNode

export function createRouteMethods(routes: Resolved<Route>[]): Record<string, Node> {
const methods: Record<string, any> = {}

routes.forEach(route => {
const currentLevel = traverseParents(route, methods)
const routeNode = createNodeForRoute(route)

console.log(JSON.stringify(thing))
Object.assign(routeNode, currentLevel[route.name])

return methods
}, {})
currentLevel[route.name] = routeNode
})

return methods
}

export function assembleRouteParentContext(route: Resolved<Route>, parentNames: string[]): Record<string, any> {
const nextLevel = parentNames.shift()
function traverseParents(route: Resolved<Route>, currentLevel: Record<string, any>): Record<string, any> {
route.parentNames.forEach(parentName => {
if (!currentLevel[parentName]) {
currentLevel[parentName] = {}
}

if (!nextLevel) {
return isPublicRoute(route.matched) ? routeMethodInstance(route) : {}
}
currentLevel = currentLevel[parentName]
})

return {
[nextLevel]: assembleRouteParentContext(route, parentNames),
}
return currentLevel
}

export type RouteMethodInstance = (values: Record<string, unknown[]>) => { url: string }
function routeMethodInstance(route: Resolved<Route>): RouteMethodInstance {
return (values) => {
const url = assembleUrl(route, values)
function createNodeForRoute(route: Resolved<Route>): Node {
if (isPublicRoute(route.matched)) {
return createCallableNode(route)
}

return { url }
return {}
}

function createCallableNode(route: Resolved<Route>): CallableNode {
const node: CallableNode = (values) => {
return {
push: () => null,
replace: () => null,
url: assembleUrl(route, values),
}
}

return node
}

0 comments on commit 4869821

Please sign in to comment.