Основываясь на ваших комментариях, я немного изменил код и написал функцию рэпера для вашего поиска. Следующие правила, которые вы должны соблюдать при создании URL:
- Последний идентификатор всегда заменяется на {id}
- Все остальные идентификаторы заменяются частью URL на идентификатор без множественное число и присоединенный "Id" ("/ users / 111" -> "/ users / {userId}")
Это будет функция:
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;
как параметр Вы передаете в качестве первого параметра url для сопоставления, а в качестве второго параметра - карту маршрутов и вызываете функцию getRoute () вместо прямой map.get (), вызывающей вас при использовании ранее.
Вот Пример с URL, настроенными в соответствии с правилами, так как вам нужны некоторые правила, чтобы иметь возможность применять RegEx.
РЕДАКТИРОВАТЬ:
Я настроил сценарий так, чтобы он сначала читал карту и определял разрешенные пути, которые принимают идентификатор, а затем проверяет возможные идентификаторы из фактического URL против него.
https://codesandbox.io/s/kind-moon-9oyj9?fontsize=14&hidenavigation=1&theme=dark