Skip to content

Instantly share code, notes, and snippets.

@aksel
Last active June 28, 2019 21:45
Show Gist options
  • Select an option

  • Save aksel/31c05995e8dc5e8d5b6f7bb0c71cf2b4 to your computer and use it in GitHub Desktop.

Select an option

Save aksel/31c05995e8dc5e8d5b6f7bb0c71cf2b4 to your computer and use it in GitHub Desktop.

Revisions

  1. aksel renamed this gist Nov 30, 2017. 1 changed file with 0 additions and 0 deletions.
    File renamed without changes.
  2. aksel created this gist Nov 30, 2017.
    36 changes: 36 additions & 0 deletions middleware.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,36 @@
    import { startsWithSegment } from 'router5-helpers';
    import { transitionPath } from 'router5';

    // Reduces the activated routes, so the last status is used, defaulting to 200
    // Reducingg instead of finding, assures that child routes determine the status codes, even when a parent has a different one.
    export const statusCodeDecorator = routes => () => (toState, fromState) => {
    const status = getActivatedRoutes(routes, toState, fromState).reduce((s, route) => route.status || s, 200);
    return Promise.resolve({ ...toState, status });
    };

    function getActivatedRoutes(routes, toState, fromState) {
    const { toActivate } = transitionPath(toState, fromState);
    return toActivate.map(segment => getRoute(segment, routes));
    }

    // Recursively traverse routes, until route matching the segment is found.
    // Returns route object.
    // Throws error if none is found.
    function getRoute(segment, routes) {
    for (let i = 0; i < routes.length; i += 1) {
    const route = routes[i];
    if (route.name === segment) {
    return route;
    }

    // Segment is child route of current route.
    if (startsWithSegment(segment, route.name) && route.children) {
    const splitSegment = segment.split('.');
    splitSegment.shift();
    if (splitSegment.length > 0) {
    return getRoute(splitSegment.join('.'), route.children);
    }
    }
    }
    throw new Error('route not found');
    };
    19 changes: 19 additions & 0 deletions router.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,19 @@
    import createRouter from 'router5';
    import listenersPlugin from 'router5/plugins/listeners';
    import browserPlugin from 'router5/plugins/browser';

    import { statusCodeDecorator } from './middlewares';

    import routes from './routes';

    export function configureRouter() {
    const router = createRouter(routes, {
    defaultRoute: 'main',
    trailingSlash: true,
    strictQueryParams: true,
    }).usePlugin(browserPlugin({ useHash: false }))
    .usePlugin(listenersPlugin());

    router.useMiddleware(statusCodeDecorator(routes));
    return router;
    }
    21 changes: 21 additions & 0 deletions routes.js
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,21 @@
    export default [
    {
    path: '/',
    name: 'main',
    },
    {
    path: '/404',
    name: '404',
    status: 404,
    },
    {
    path: '/401',
    name: '401',
    status: 401,
    },
    {
    path: '/500',
    name: '500',
    status: 500,
    },
    ];