Как проверить, является ли строка действительной ссылкой Figma? - PullRequest
1 голос
/ 30 марта 2019

Я создаю приложение на NodeJS, которое использует API Figma, и мне нужно проверить, является ли строка, переданная пользователем, действительной ссылкой Figma.В настоящее время я использую это простое выражение регулярного выражения для проверки строки:

/^https\:\/\/www.figma.com\/.*/i

Однако оно соответствует всем ссылкам с figma.com, даже домашней странице, а не только ссылкам на файлы и прототипы.Вот пример ссылки Figma, которая должна соответствовать:

https://www.figma.com/file/OoYmkiTlusAzIjYwAgSbv8wy/Test-File?node-id=0%3A1

Также соответствие должно быть положительным, если это ссылка прототипа, с proto вместо file в пути.

Более того, поскольку я использую API Figma, было бы полезно извлечь необходимые части URL-адреса, такие как идентификатор файла и идентификатор узла.

1 Ответ

1 голос
/ 30 марта 2019

TL; DR

✅ Используйте это выражение для захвата четырех наиболее важных групп (тип, идентификатор файла, имя файла и свойства URL) и работайте оттуда.

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?(.*))?$/

Из документов

Это код выражения регулярного выражения, предоставленный Figma на их странице документации для разработчиков по встраиваниям :

/https://([w.-]+.)?figma.com/(file|proto)/([0-9a-zA-Z]{22,128})(?:/.*)?$/

? Однако, он не работает в JS, поскольку документация в настоящее время неверна , и это выражение имеет несколько проблем:

  • Косые черты и точки не защищены от обратных косых черт.

  • Не совпадает с начала строки. Я добавил начало привязки строк ^ после того, как VLAZ указал на это в комментариях. Таким образом, мы избежим совпадения строк, которые не начинаются с https, например malicious.site/?link=https://figma.com/...

  • Он будет соответствовать не только www. поддомену, но и любому другому количеству W, которое невелико (например, wwwww.) - его можно исправить, заменив сопоставление букв более простым выражением. Также это бесполезная группа захвата, я сделаю это без захвата.

  • Было бы неплохо, если бы ссылка соответствовала, даже если она не начинается с https://, поскольку некоторые движки (например, Twitter) для краткости отбрасывают эту часть, и если человек копирует ссылку оттуда, она все равно должна быть действительным.

После применения всех улучшений у нас остается следующее выражение:

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?$/

Существует также выделенный пакет NPM , который просто проверяет URL по аналогичному шаблону. Тем не менее, он содержит некоторые недостатки, перечисленные выше, поэтому я не советую использовать его, особенно для одной строки кода.


Извлечение частей URL

Это выражение чрезвычайно полезно для использования с API Figma, поскольку оно даже извлекает из URL необходимые части, такие как тип ссылки (proto / file) и ключ file . Вы можете получить к ним доступ по индексам.

Вы также можете добавить фрагмент регулярного выражения для соответствия определенным ключам в запросе, например node-id:

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?node-id=([^&]*)$/

Теперь вы можете использовать его в коде и получать все части URL отдельно:

var pattern = /^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/.*)?node-id=([^&]*)$/

var matched = 'https://www.figma.com/file/OoYmkiTlusAzIjYwAgSbv8wy/Test-File?node-id=0%3A1'.match(pattern)

console.log('url:', matched[0]) // whole matched string
console.log('type:', matched[1]) // group 1
console.log('file key:', matched[2]) // group 2
console.log('node id:', matched[3]) // group 3

копать глубже

Я потратил некоторое время на то, чтобы воссоздать это выражение практически с нуля, чтобы оно соответствовало как можно большему количеству возможных URL-адресов файлов / прототипов Figma без каких-либо проблем. Вот три аналогичные версии, которые будут работать для разных случаев.

✅ В этой версии параметры URL и имя файла записываются отдельно для упрощения обработки. Вы можете проверить это здесь . Я добавил его в начале ответа, потому что считаю, что это самое чистое и полезное решение.

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?(.*))?$/

Группы в нем следующие:

  • Группа 1: файл / протокол
  • Группа 2: ключ файла / id
  • Группа 3: имя файла (необязательно)
  • Группа 4: параметры URL (необязательно)

✅ Далее я хотел сделать то же самое, но отделив часть /duplicate, которая может быть добавлена ​​в конце любого URL-адреса Figma для создания дубликата файла при открытии.

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/?([^\?]+)?([^\/]*)(\/duplicate)?)?$/

✅ И вернемся к параметру node-id. Следующее выражение регулярного выражения успешно находит и захватывает несколько URL-адресов внутри многострочной строки . Единственный недостаток, который я обнаружил в конце, это то, что он (как и все предыдущие) не проверяет, содержит ли этот URL незашифрованные специальные символы , что означает, что он потенциально может что-то сломать, но это может быть избежать ручного кодирования всех параметров с помощью функции encodeURI() .

/^(?:https:\/\/)?(?:www\.)?figma\.com\/(file|proto)\/([0-9a-zA-Z]{22,128})(?:\/([^\?\n\r\/]+)?((?:\?[^\/]*?node-id=([^&\n\r\/]+))?[^\/]*?)(\/duplicate)?)?$/gm

Есть шесть групп, которые могут быть охвачены этим выражением:

  • Группа 1: файл / протокол
  • Группа 2: ключ файла / id
  • Группа 3: имя файла (необязательно)
  • Группа 4: параметры URL (необязательно)
    • Группа 5: идентификатор узла (необязательно; присутствует только при наличии группы 4)
  • Группа 6: / duplicate

И, наконец, вот примерматч и его группы (или попробуйте сами ):

groups examples

...