Проверьте, существует ли URL с параметром в массиве - PullRequest
0 голосов
/ 08 января 2020

У меня есть массив с URL-адресами, которые использует swagger, что-то вроде:

["PATCH /users/{userId}",
"PATCH /users/types/{userIdId}",
"PATCH /products/brands/{brandId}/image",
"PATCH /product-types/{productId}"];

Я использую Mongodb в качестве базы данных, и идентификаторы похожи, например, на userId = "5dce7b7e47224c477734e35d". Вот код внутри моей функции:

var havePerm = false;
var myUrl = "PATCH /users/5dce7b7e47224c477734e35d"
for (var i = 0; i < urls.length; i++) {
   // It compares if: "PATCH /users/5dce7b7e47224c477734e35d" equals "PATCH /users/{userId}"
   if (myUrl === urls[i]) { 
      havePerm = true;
   }
}
return havePerm;

В этом случае он должен возвращать true, но возвращает false.

Если URL-адреса не имеют параметра (пример: {id }), сравнение прямое, но в случае PATCH проблема в том, что я не знаю, как сравнить параметр между фигурными скобками {}.

Как я могу сравнить эти случаи? с регулярным выражением? но я не знаю, как его построить.

1 Ответ

0 голосов
/ 08 января 2020

Вы можете разбить строки (компоненты метода и пути), а затем сравнить детали, вот пример:

const urls = ["PATCH /users/{userId}",
  "PATCH /users/types/{userIdId}",
  "PATCH /products/brands/{brandId}/image",
  "PATCH /product-types/{productId}"
];

const myUrl = "PATCH /users/5dce7b7e47224c477734e35d";

function parse(str) {
  return str.split(/\s?\//);
}

function isPlaceholder(str) {
  return /\{[^}]+\}/.test(str);
}

function hasPermission() {
  const myUrlParsed = parse(myUrl);
  // check if any of the "urls" elements matches "myUrl"
  return urls.some(url => {
    const parsedUrl = parse(url);
    if (myUrlParsed.length === parsedUrl.length) {
      // check if all the "myUrlParsed" elements match all "parsedUrl" elements at the coresponding index or if the "parsedUrl" element is a placeholder
      return myUrlParsed.every((v, i) => v === parsedUrl[i] || isPlaceholder(parsedUrl[i]));
    }
    return false;
  });
}

console.log("has permission:", hasPermission());

Для этого нужно разбить каждый URL-адрес до массива, который выглядит следующим образом:

["PATCH", "users", "{userId}"]

, а затем проверить каждый из этих видов массивов повторяет массив, сгенерированный из строки myUrl.

Проверка проверяет, равен ли каждый элемент массива по соответствующему индексу или заполнитель (начинается с { и оканчивается на }).

Другим способом сделать это будет преобразование URL в регулярные выражения, вот пример:

let urls = ["PATCH /users/{userId}",
  "PATCH /users/types/{userIdId}",
  "PATCH /products/brands/{brandId}/image",
  "PATCH /product-types/{productId}"
];
const myUrl = "PATCH /users/5dce7b7e47224c477734e35d";

function escapeRegex(s) {
  return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
};

urls = urls.map(url => {
  const regExpStr = url.split(/\{[^\}]+\}/)
    .map(escapeRegex)
    .join('[^\/]+');
  return new RegExp(regExpStr);
});

function hasPermission() {
  return urls.some(url => url.test(myUrl));
}

console.log("Has permission:", hasPermission());
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...