Skip to content

Commit

Permalink
Merge pull request #27 from stack-spot/fix/nested-wildcards-route-ide…
Browse files Browse the repository at this point in the history
…ntification

Fix: nested wildcards route identification
  • Loading branch information
Tiagoperes authored Sep 9, 2024
2 parents db30cb9 + 0451ced commit 1c31511
Show file tree
Hide file tree
Showing 4 changed files with 45 additions and 5 deletions.
2 changes: 1 addition & 1 deletion packages/runtime/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@stack-spot/citron-navigator",
"version": "1.5.0",
"version": "1.6.0",
"type": "module",
"main": "dist/index.js",
"types": "dist/index.d.ts",
Expand Down
14 changes: 10 additions & 4 deletions packages/runtime/src/CitronNavigator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,14 +143,20 @@ export class CitronNavigator {
}, [])
}

private findRouteByPath(route: Route, path: string): Route | undefined {
private findRouteByPath(route: Route, path: string, lastMatch?: Route): Route | undefined {
switch (route.$match(path)) {
case 'exact': return route
case 'exact':
return route.$path.endsWith('*')
? this.childrenOf(route).reduce<Route | undefined>(
(result, child) => result ?? this.findRouteByPath(child, path, route),
undefined,
) ?? route
: route
case 'subroute':
return this.childrenOf(route).reduce<Route | undefined>(
(result, child) => result ?? this.findRouteByPath(child, path),
(result, child) => result ?? this.findRouteByPath(child, path, lastMatch),
undefined,
) ?? (route.$path.endsWith('*') ? route : undefined)
) ?? (route.$path.endsWith('*') ? route : lastMatch)
}
}

Expand Down
18 changes: 18 additions & 0 deletions packages/runtime/test/CitronNavigator.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,24 @@ describe('Citron Navigator', () => {
expect(navigator.currentParams).toEqual({ studioId: 'studio1', stackId: 'stack1', starterId: 'starter1', str: 'test' })
}))

describe('should use deep wildcard instead of shallow', testHash({
routeFactory: () => new AlternativeRootRoute(),
testFn: ({ p, navigator, route: root }) => {
mockLocation(`https://www.stackspot.com${p('/workspaces/a/stacks')}`)
navigator.updateRoute()
expect(navigator.currentRoute).toBe(root.workspaces.workspace.stacks)
expect(navigator.currentParams).toEqual({ workspaceId: 'a' })
mockLocation(`https://www.stackspot.com${p('/workspaces/a')}`)
navigator.updateRoute()
expect(navigator.currentRoute).toBe(root.workspaces.workspace)
expect(navigator.currentParams).toEqual({ workspaceId: 'a' })
mockLocation(`https://www.stackspot.com${p('/workspaces')}`)
navigator.updateRoute()
expect(navigator.currentRoute).toBe(root.workspaces)
expect(navigator.currentParams).toEqual({})
},
}))

describe('should deserialize route parameters', testHash({
locationFactory: (p) => {
const urlParams = [
Expand Down
16 changes: 16 additions & 0 deletions packages/runtime/test/routes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,22 @@ export class WorkspacesRoute extends Route<AlternativeRootRoute, void> {
constructor(parent: AlternativeRootRoute) {
super('root.workspaces', '/workspaces/*', parent, {})
}

workspace = new WorkspaceRoute(this)
}

export class WorkspaceRoute extends Route<WorkspacesRoute, { workspaceId: string }> {
constructor(parent: WorkspacesRoute) {
super('root.workspaces.workspace', '/workspaces/{workspaceId}/*', parent, { workspaceId: 'string' })
}

stacks = new WorkspaceStacksRoute(this)
}

export class WorkspaceStacksRoute extends Route<WorkspaceRoute, void> {
constructor(parent: WorkspaceRoute) {
super('root.workspaces.workspace.stacks', '/workspaces/{workspaceId}/stacks/*', parent, { workspaceId: 'string' })
}
}

export class AccountRoute extends Route<RootRoute, RouteParams['root.account']> {
Expand Down

0 comments on commit 1c31511

Please sign in to comment.