Based on your comments i adjusted the code a bit and wrote a rapper function for your lookup.
The following rules you have to watch out for when creating the urls:
- The last id always gets replaced by {id}
- All other ids get replaced by url part to id without plural and "Id" attached ("/users/111" -> "/users/{userId}")
This would be the function:
const getRouteFromPath = (map, url) => {
if (url.match(/\/\d+\//g).length > 1) {
let allowedUrlPart = getAllowedIdQualifier(map);
let urlParts = url.match(/(?<=\/)\w+(?=\/\d+\/)/g);
urlParts.forEach(val => {
if (!allowedUrlPart.includes(val)) {
urlParts = urlParts.slice(urlParts.indexOf(val), 1);
}
});
urlParts.forEach((val, key, arr) => {
if (key === arr.length - 1) {
let regex = new RegExp("(?<=/" + val + "/)\\d+", "g");
let replacement = ":id";
url = url.replace(regex, replacement);
} else {
let regex = new RegExp("(?<=/" + val + "/)\\d+", "g");
let replacement = ":" + val.slice(0, -1) + "Id";
url = url.replace(regex, replacement);
}
});
return map.get(url);
} else {
url = url.replace(/\/\d+\//g, "/:id/");
return map.get(url);
}
};
const getAllowedIdQualifier = map => {
let allowedQualifiers = [];
map.forEach(val => {
let allowed = val.path.match(/(?<=\/)\w+(?=\/:)/g);
allowed.forEach(e => {
if (!allowedQualifiers.includes(e)) {
allowedQualifiers.push(e);
}
});
});
return allowedQualifiers;
};
export default getRouteFromPath;
As parameter you pass in the url to match as first parameter and the map of routes as the second paramter and call the function getRoute() instead of the direct map.get() call you where using before.
Here is the example with the urls adjusted to follow the rules, since you need some rules to be able to apply RegEx.
EDIT:
I adjusted the script, so that it reads the map first and determines the allowed paths which accept a id and then check the possible ids from an actual url against it.
https://codesandbox.io/s/kind-moon-9oyj9?fontsize=14&hidenavigation=1&theme=dark