Главная/Языки/Алиасы и нормализация ENУКРРУС API-справочник (ReDoc) ↗

Алиасы и нормализация

Как любое написание кода попадает на правильный язык — включая сломанные.

Коды приходят из экспортов TMS, клиентских API, таблиц и десятилетия накопленных интеграций. Они мало в чём согласны между собой. Нормализация — это то, что делает их сравнимыми.

Две формы кода

Ключ поиска — нижний регистр, разделитель -, пробелы срезаны. pt_BR, PT-BR, pt-br и pt - br становятся pt-br. Алиасы хранятся в этой форме и сверяются точным равенством, так что горячий путь — одно индексированное сравнение, а не LIKE-скан.

Каноническая форма — регистр BCP-47: первичный сабтег строчными, скрипт с заглавной, регион прописными. pt-BR, zh-Hans, sr-Latn-RS. Именно это возвращает API и именно это стоит хранить.

Канонизация также исправляет порядок сабтегов. Консоль держит и sr-Latn-RS, и sr-RS-Latn для одного языка; BCP-47 ставит скрипт перед регионом, так что оба парсятся в один тег и рендерятся как sr-Latn-RS.

Исправление гомоглифов

Перед вычислением обеих форм коды проходят через проверку гомоглифов.

Это не гипотетически. База консоли содержит сeb для себуанского, где первый символ — U+0441 CYRILLIC SMALL LETTER ES, а не ASCII c. Он выглядит идентично в любом шрифте и никогда не совпадает с тем, что присылает вызывающий, — именно так себуанский стал фактически недостижимым для нескольких провайдеров.

Исправление мапит кириллические буквы, визуально идентичные латинским — а е о р с х у і ј, — и только когда результат становится чистым ASCII, так что действительно кириллическое значение остаётся нетронутым, а не искажённым. Полноширинная латиница (en) сворачивается через NFKC в том же проходе.

Откуда берутся алиасы

Источник Примеры Зачем
canonical собственный код языка всегда присутствует
console es-la, ES-LA для es-419 все написания из легаси-базы, включая проигравших в неоднозначных парах
curated deu, ger, zho, iw, in, ji, mo ISO 639-2/3 и устаревшие ISO 639-1, которые до сих пор шлют экспорты TMS
provider написание провайдера, отличное от победителя держит проигравшую сторону свёрнутой пары достижимой
manual то, с чем пришла новая интеграция добавляется из [[Admin-Panel

Уникальность

Алиас принадлежит ровно одному языку, глобально. Это обеспечивает база данных, а не договорённость.

Это важно, потому что входящий резолвинг обязан быть функцией. Консоль допускала, чтобы zh-CN был одновременно в «Chinese (PRC)» и «Chinese (Simplified)», fa-AF — в «Dari» и «Farsi (Afghanistan)», bn-BD — в двух бенгальских строках. get_language_by_code резолвил это через .first() — неупорядоченный запрос.

Билдер сида решает каждый конфликт один раз:

  1. язык, чей канонический код и есть этот алиас,
  2. далее тот, который консоль пометила is_default,
  3. далее тот, у кого больше маппингов провайдеров — то есть тот, который прод действительно использует,
  4. далее наименьший легаси-id, то есть то, что .first() отдаёт сегодня.

Каждое решение перечислено в data/seed/REPORT.md, так что те, что стоят спора, видны, а не похоронены.

Для чего алиас не нужен

Для вариантов регистра и разделителей. pt_BR уже совпадает с алиасом pt-br; добавлять pt_br отдельной строкой избыточно.

Проверить код, не резолвя его

/v1/normalize отвечает на вопрос без провайдера — что это за язык и как мы его называем?

curl "https://languages.service.custom.mt/v1/normalize?language=ZH_HANS"
{ "query": "ZH_HANS", "known": true, "matched_alias": "zh-hans",
  "language": { "code": "zh-CN", "name": "Chinese (Simplified)", "aliases": ["chs", "zh-hans", ] } }

В отличие от других эндпоинтов, неизвестный код здесь не ошибкаknown: false приходит с 200. Это позволяет классифицировать весь список за один проход, а не ловить 404. См. Нормализация входящих кодов.

Далее