Skip to content

Instantly share code, notes, and snippets.

@aksel
Last active June 28, 2019 21:45
Show Gist options
  • Save aksel/31c05995e8dc5e8d5b6f7bb0c71cf2b4 to your computer and use it in GitHub Desktop.
Save aksel/31c05995e8dc5e8d5b6f7bb0c71cf2b4 to your computer and use it in GitHub Desktop.
Route HTTP status code middleware for router5
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');
};
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;
}
export default [
{
path: '/',
name: 'main',
},
{
path: '/404',
name: '404',
status: 404,
},
{
path: '/401',
name: '401',
status: 401,
},
{
path: '/500',
name: '500',
status: 500,
},
];
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment