Как устроена платформа плагинов
Плагин — это отдельное фронтовое приложение на JavaScript, которое запускается в iframe внутри приложения Трекера. Для его разработки предоставляется SDK. Приоритетным считается использование React. Также существует библиотека на чистом JavaScript, которая позволяет не привязываться к React.
Платформа покрывает полный жизненный цикл плагинов: предоставляет инструменты разработки и отладки, версионирования и публикации, а также репозиторий для хранения плагинов. Администраторы могут устанавливать, обновлять и отключать плагины, контролируя их доступность для пользователей и контекстов.
Выполнение плагина в iframe
Интерфейсная часть плагинов представляет собой статику, которая размещена на серверах Трекера. Она выполняется в изолированном iframe на безкуковом домене, которому запрещено почти всё, включая сетевые запросы. Поэтому общение с сервисами Яндекса, публичным API Трекера и внешним миром осуществляется через SDK. Исключение — прямые запросы к внешним доменам, явно разрешенным в манифесте.
SDK
Работа с Трекером осуществляется с помощью SDK, который подключается как библиотека. SDK предоставляет методы взаимодействия на уровне пользовательского интерфейса, методы для работы с публичным API Трекера и хранилище данных плагина.
SDK поставляется двумя npm-пакетами:
- core — API-клиент и базовые примитивы интеграции (JS/TS).
- react — React-обертки над core для удобной разработки UI.
CLI
CLI — это консольная утилита в виде NPM пакета, которая обеспечивает весь жизненный цикл плагина: создание, отладка, проверка и публикация.
UI-компоненты
Библиотека UI-компонентов в стилистике Трекера, доступных для использования в плагинах.
Манифест
Манифест — это файл manifest.json в корне проекта. Он описывает плагин, запрашиваемые разрешения и точки интеграции с Трекером.
JSON Schema
При создании проекта CLI добавляет рядом с манифестом файл manifest.schema.json и указывает его в поле $schema:
{
"$schema": "./manifest.schema.json"
}
Редактор кода использует схему для проверки манифеста, автодополнения и показа допустимых значений. CLI проверяет манифест по встроенной схеме, даже если поле $schema отсутствует. Не редактируйте manifest.schema.json вручную. Чтобы обновить локальную схему и остальные файлы шаблона, выполните команду weavix up.
Ограничения и списки допустимых значений могут меняться. Проверяйте их в manifest.schema.json текущего проекта.
Поля манифеста
|
Поле |
Тип |
Обязательное |
Описание |
|
|
|
Нет |
Путь к JSON Schema. CLI добавляет значение |
|
|
|
Нет |
Версия формата манифеста. CLI добавляет значение |
|
|
|
Нет |
Сервисы, в которых работает плагин. Для плагина Трекера укажите |
|
|
|
Да |
Уникальное имя плагина из строчных латинских букв, цифр и дефисов. Длина — от 3 до 63 символов |
|
|
|
Нет |
Идентификатор плагина на платформе. CLI добавляет его при регистрации во время первой отправки командой |
|
|
|
Да |
Версия плагина в формате SemVer, например |
|
|
|
Да |
Название на русском и английском языках в полях |
|
|
|
Да |
Описание на русском и английском языках в полях |
|
|
|
Да |
Непустой список контактов поддержки. Каждый объект содержит |
|
|
|
Да |
Разрешения, необходимые плагину. В объекте обязательно поле |
|
|
|
Нет |
Точки интеграции плагина с интерфейсом сервисов |
|
|
|
Нет |
Категории, по которым плагин отображается в каталоге |
|
|
|
Нет |
Адрес справки плагина |
|
|
|
Нет |
Адрес сайта плагина с протоколом HTTP или HTTPS |
|
|
|
Нет |
Идентификатор лицензии длиной до 32 символов, например |
|
|
|
Нет |
Уникальные ключевые слова для поиска плагина. Длина каждого значения — до 30 символов |
|
|
|
Нет |
Описание изменений в версии длиной до 300 символов |
|
|
|
Нет |
HTTPS-адрес, с которого загружается интерфейс плагина. Использование внешнего хоста требует согласования с командой Трекера |
Настройка слотов
Плагин может использовать несколько точек интеграции. Для каждой точки укажите:
entrypoint— путь к входному HTML-файлу;title— название элемента интерфейса на русском и английском языках;contextLevel— уровень данных, доступных плагину:basic— идентификатор текущей сущности и базовые метаданные;full— полный объект сущности, например все поля задачи;
description— необязательное описание на русском и английском языках;
Используйте full, только если плагину необходим полный объект сущности.
Поле slots не является обязательным по формату манифеста, но для проверки и публикации проекта необходимо настроить хотя бы один слот.
"slots": {
"tracker": {
"issue.action": [
{
"entrypoint": "index.html",
"contextLevel": "basic",
"title": {
"ru": "Мой плагин",
"en": "My Plugin"
}
}
]
}
}
Разрешения
В манифесте укажите только те разрешения, которые необходимы плагину. Объект permissions содержит следующие поля:
data— обязательный массив разрешений на работу с данными Трекера. Разрешения имеют форматtracker:<ресурс>:readдля чтения иtracker:<ресурс>:writeдля изменения данных. Например,tracker:issues:readпозволяет читать задачи,tracker:issues:write— изменять их, аtracker:attachments:write— загружать вложения. Актуальный список допустимых значений приведен вmanifest.schema.json;device— доступ к возможностям устройства пользователя. Допустимые значения:clipboard-write,microphone,camera,geolocation,web-shareиallow-downloads. Если это предусмотрено браузером, пользователь должен дополнительно разрешить доступ к выбранной возможности;ui— дополнительные действия в интерфейсе Трекера. Добавляйте такое разрешение, только если оно указано в описании используемого метода SDK;external— домены внешних API, способ доступа к ним (access) и параметры авторизации. Основной способ — запросы через прокси платформы (proxy). Прямые запросы из браузера (direct) не поддерживают авторизацию и не рекомендуются к использованию. Подробнее см. в разделе Внешние API.
Уровень доступа
Разрешение в манифесте не расширяет права пользователя. Все действия выполняются от имени текущего пользователя и в пределах выданных ему прав.
Хранилище данных плагинов
Платформа предоставляет плагину собственное JSON-хранилище — storageApi. Данные хранятся на стороне платформы, поэтому не зависят от устройства пользователя. Область видимости записи определяет контекст:
orgShared— общая запись на всю организацию. Подходит для общих настроек плагина и кешей справочников.user— личная запись текущего пользователя. Подходит для персональных настроек и состояния интерфейса.resource— запись, привязанная к ресурсу Трекера по идентификаторуresourceId, напримерissue:MYQUEUE-123илиqueue:MYQUEUE. Запись общая для всех пользователей, которые обращаются к этому ресурсу.
Внутри контекста плагин может хранить несколько независимых записей — они разделяются по ключу bucket. Операция get читает запись, patch создает или изменяет ее по merge-семантике: значение null удаляет поле. Конкурентные изменения контролируются версией записи (optimistic locking).
Подробнее о текущей реализации хранилища и его API — в разделе Хранилище данных плагина.
Доступ к внешним API через прокси
Платформа предоставляет безопасный механизм интеграций с внешними сервисами: прокси платформы для выполнения HTTP-запросов и авторизацию этих запросов личным токеном пользователя.
-
Прокси платформы — единая точка для вызовов внешних API от имени плагина. Плагин отправляет параметры запроса: URL, метод, заголовки, тело. Платформа выполняет запрос на бекенде и возвращает результат. Доступ ограничивается декларативно (allowlist доменов). Платформа блокирует небезопасные направления (приватные сети/localhost, неразрешенные редиректы), ведет аудит и применяет rate limit по
pluginIdи организации. -
Авторизация прокси-запросов — автор плагина описывает в манифесте, какой токен нужен для домена и в какой заголовок его подставить. Сам токен в манифесте не указывается. Если токена еще нет, Трекер показывает пользователю диалог ввода токена с инструкцией автора плагина. Токен хранится на стороне платформы и не передается в iframe плагина: плагин узнает только, есть ли авторизация. При запросах через прокси платформа подставляет токен автоматически. Поддерживаются только личные токены пользователя — контекст
user.
Подробнее о том, как вызывать внешние API из плагина, — в разделе Внешние API.
Плагин также может отправлять прямые запросы к внешним API из браузера. Платформа в таких запросах не участвует: они не поддерживают авторизацию, аудит и защиту прокси, поэтому не рекомендуются к использованию.
Точки интеграции (слоты)
Место, в котором плагин будет открыт, а также механизм его вызова (кнопка или как часть формы, например), определяется слотом. Слот указывается в манифесте.
Доступные слоты и детали их использования описаны в разделе Точки интеграции.
Контекст запуска плагина
Контекст запуска плагина определяется слотом, в котором он находится и содержит следующую информацию:
- Текущая тема Трекера
- Текущий язык Трекера
- Контекст слота — данные из окружения страницы, в которой запущен плагин. Например, в слоте
issue.actionвернется информация по открытому тикету. Формат контекста максимально приближен к типам публичного API.
Уровни контекста слота
Уровень контекста задается параметром contextLevel в описании слота в manifest.json и определяет, какие данные будут доступны плагину через useTrackerPluginContext.
basic
Доступен только идентификатор текущей сущности и базовые метаданные:
type BasicContext = {
/** Идентификатор текущей сущности */
entityId: string;
/** Дополнительная базовая информация о сущности.
* Например, для комментария здесь будет идентификатор родительского тикета. */
entityMeta?: Record<string, string>;
};
Используйте basic, если плагину достаточно знать идентификатор сущности — это более легкий вариант без лишней нагрузки.
full
Полный контекст с живыми данными сущности. Формат совпадает с типами публичного API. Например, для слота issue.action — полный объект Issue. Данные актуальны на момент открытия плагина.
Используйте full, только если плагину действительно нужны полные данные сущности.
Выбор уровня контекста
Запрашивайте только тот уровень контекста, который реально нужен плагину. При отсутствии необходимости в полных данных сущности используйте basic.