Write a tiny client-side router that matches paths like /users/:id.
createRouter(routes) takes an array of { path, handler } and returns { resolve(url) }. Patterns are split on /. A segment starting with : matches any one segment and captures it as a named param. A * as the last segment matches the rest of the path, possibly nothing, and captures it as params["*"].
resolve takes a path that may include a ?query or #hash, which it ignores. It calls the handler of the first route that matches as handler(params) and returns the result, or returns null when nothing matches. Decode named params with decodeURIComponent. Empty segments don't count, so a trailing slash makes no difference.
function createRouter(routes) {
// your code
}
// const router = createRouter([
// { path: "/", handler: () => "home" },
// { path: "/users/:id", handler: ({ id }) => `user ${id}` },
// { path: "/files/*", handler: (params) => `file ${params["*"]}` },
// { path: "*", handler: () => "not found" },
// ]);
// router.resolve("/users/42?tab=posts"); // "user 42"
// router.resolve("/files/docs/a.txt"); // "file docs/a.txt"
// router.resolve("/pricing"); // "not found"
Solve it in the editor, with tests
The answer
Write it yourself first. Then compare it with a reference solution and the checks it passes.
Checking your sign-in…