API Reference - @weavix/sdk-core
hostApi (HostApi)
API для взаимодействия с хостом Tracker: инициализация плагина, тема, язык, контекст слота, размер окна, уведомление о готовности.
Экспортируется singleton hostApi. Обычно используется внутри TrackerPluginProvider из пакета react. При необходимости можно вызывать напрямую.
init()
Инициализирует плагин: читает параметры из URL, инициализирует мост, при необходимости выполняет авто-ресайз. Вызывать один раз перед использованием остальных методов.
Parameters: options?: HostInitOptions — опции (например autoResize, по умолчанию true).
Throws: Error — если в URL нет обязательных параметров (slot, parentOrigin, id, elementId).
import { hostApi } from "@weavix/sdk-core";
hostApi.init({ autoResize: true });
getTheme()
Возвращает текущую тему хоста.
Returns: Promise<Theme>
const theme = await hostApi.getTheme(); // 'light' | 'light-hc' | 'dark' | 'dark-hc' | 'system'
getLanguage()
Возвращает текущий язык хоста.
Returns: Promise<string> (например 'ru', 'en').
const language = await hostApi.getLanguage();
getContext()
Возвращает контекст слота, в котором запущен плагин. Уровень возвращаемых данных определяется параметром contextLevel, указанным для слота в manifest.json. Подробнее — в разделе Уровни контекста слота.
Parameters: level: 'basic' | 'full' (обязательный)
Returns:
- При
level: 'basic'—Promise<BasicContext>, гдеBasicContext = { entityId: string; entityMeta?: Record<string, string> } - При
level: 'full'—Promise<SlotContextMap[TSlot]>
// Базовый контекст (только идентификатор сущности)
// Требует contextLevel: 'basic' в manifest.json для данного слота
const basicContext = await hostApi.getContext("basic");
// basicContext.entityId — идентификатор текущей сущности
// basicContext.entityMeta — дополнительные метаданные (опционально)
// Полный контекст (все данные сущности)
// Требует contextLevel: 'full' в manifest.json для данного слота
const fullContext = await hostApi.getContext("full");
updateContentSize()
Отправляет хосту запрос на изменение размеров окна плагина.
Parameters: payload: ContentSizeUpdateRequest (поля height и width - хотя бы одно должно присутствовать).
Returns: Promise<…>
await hostApi.updateContentSize({ height: 500 }); // задает высоту окна плагина
await hostApi.updateContentSize({ width: 800 }); // задает ширину окна плагина
await hostApi.updateContentSize({ height: 500, width: 800 }); // задает высоту и ширину окна плагина
Ширина окна плагина применяется с учетом ограничений места встраивания.
notifyReady()
Сообщает хосту, что плагин готов к работе.
Returns: Promise<…>
await hostApi.notifyReady();
getSlot()
Возвращает текущий слот. Вызывать только после init().
Returns: TSlot (ключ из SlotContextMap).
const slot = hostApi.getSlot(); // например 'issue.action'
disableAutoResize()
Отключает автоматическое изменение размера контейнера по контенту.
hostApi.disableAutoResize();
close()
Закрытие плагина, если он показан во всплывающем окне
hostApi.close();
Передача данных
Некоторые слоты поддерживают обработку данных, которые будут переданы в качестве аргумента метода close.
Точные типы и функциональность смотрите в документации по конкретным точкам интеграции.
preventClose()
Защищает плагин от случайного закрытия пользователем, например, по Esc или клику по крестику. Если установлен флаг preventClose: true, хост заблокирует закрытие до тех пор, пока флаг не будет сброшен. Работает только с плагинами, которые отображаются в модальном окне.
Используйте этот метод, чтобы предотвратить потерю несохраненных изменений.
import { hostApi } from "@weavix/sdk-core";
// Блокируем закрытие, если есть несохраненные изменения
hostApi.preventClose({ preventClose: true });
Parameters: { preventClose: boolean }
preventClose: true— блокирует закрытие плагина пользователемpreventClose: false— снимает блокировку
Пример использования с React:
import { hostApi } from "@weavix/sdk-react";
import { useEffect, useState } from "react";
function MyEditor() {
const [content, setContent] = useState("");
const [saved, setSaved] = useState(true);
const hasChanges = !saved;
// Автоматически устанавливаем/снимаем блокировку при изменении состояния
useEffect(() => {
hostApi.preventClose({ preventClose: hasChanges });
}, [hasChanges]);
const handleSave = async () => {
await saveContent(content);
setSaved(true);
};
return (
<div>
<textarea
value={content}
onChange={(e) => {
setContent(e.target.value);
setSaved(false);
}}
/>
<button onClick={handleSave}>Сохранить</button>
</div>
);
}
Важно
- Не забывайте снимать блокировку (
preventClose: false) после сохранения данных, иначе пользователь не сможет закрыть плагин. - При принудительном закрытии, например при переходе на другой экран, хост может игнорировать блокировку.
uiApi
API для взаимодействия с пользовательским интерфейсом хоста: показ уведомления, открытие попапов и т.п.
Тосты (Toast notifications)
Плагины могут показывать toast-уведомления в хост-приложении через uiApi.toaster. API максимально приближен к useToaster из @gravity-ui/uikit.
Permission
В manifest.json нужно запросить tracker:ui:toaster:
{
"permissions": {
"ui": ["toaster"]
}
}
import { uiApi } from "@weavix/sdk-core";
// Простой тост
uiApi.toaster.add({
title: "Сохранено",
theme: "success",
});
// Тост с текстовым содержимым и кастомным временем показа
uiApi.toaster.add({
title: "Ошибка",
theme: "danger",
content: "Не удалось загрузить данные",
autoHiding: 10000,
});
// Тост с кнопкой действия
uiApi.toaster.add({
title: "Элемент удален",
theme: "info",
content: "QUEUE-123",
actions: [
{
label: "Отменить",
onClick: () => {
// обработка нажатия
},
},
],
});
Параметры
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
title |
string |
— | Заголовок тоста (обязательный) |
name |
string |
auto | Уникальный ключ для дедупликации. Генерируется автоматически, если не передан |
theme |
'success' | 'danger' | 'warning' | 'info' |
'info' |
Тема (цвет и иконка) |
content |
string |
— | Текстовое содержимое под заголовком |
autoHiding |
number |
5000 |
Время показа в мс (от 1000 до 30000) |
isClosable |
boolean |
true |
Показывать кнопку закрытия |
actions |
ToastAction[] |
— | Кнопки действий (макс. 2) |
ToastAction:
| Параметр | Тип | Описание |
|---|---|---|
label |
string |
Текст кнопки (макс. 50 символов) |
onClick |
() => void |
Callback при нажатии |
Возвращает: Promise<{ name: string }> — имя тоста (для идентификации).
Ограничения:
title— макс. 200 символовcontent— макс. 500 символовactions— макс. 2 кнопки- Rate limit — 5 тостов за 10 секунд на плагин
Обработка ошибок
import {
trackerApi,
PluginActionError,
} from "@weavix/sdk-core";
try {
await trackerApi.v3.get["/issues/{id}"]({ pathParams: { id: "BAD" } });
} catch (e) {
if (e instanceof PluginActionError) {
console.log(e.code, e.message, e.errorData);
}
}
Confirm Dialog
Плагин может показать модальный диалог подтверждения. Диалог рендерится на стороне трекера, а не внутри iframe, поэтому перекрывает всё приложение и фокусирует пользователя на принятии решения.
Permission
В manifest.json нужно запросить tracker:ui:confirm:
{
"permissions": {
"ui": ["confirm"]
}
}
import { uiApi } from "@weavix/sdk-core";
const { confirmed } = await uiApi.confirm.show({ message: "Уверены?" });
Параметры
| Параметр | Тип | Лимит | По умолчанию | Описание |
|---|---|---|---|---|
title |
string |
≤ 200 | — | Заголовок диалога |
message |
string |
≤ 500 | — (обязательно) | Текст подтверждения |
textButtonApply |
string |
≤ 50 | "OK" |
Текст кнопки подтверждения |
textButtonCancel |
string |
≤ 50 | "Отмена" |
Текст кнопки отмены |
theme |
'normal' | 'danger' |
— | 'normal' |
Тема кнопки apply |
Лимиты и ошибки
- 1 активный confirm на плагин. Попытка открыть второй, пока висит первый — промис реджектится с
CONFIRM_ALREADY_OPEN. - Максимум 5 одновременных диалогов в общей очереди (от всех плагинов). При переполнении —
QUEUE_OVERFLOW. - Таймаут 5 минут. Если пользователь не отвечает, промис реджектится с
Request timeout. - Закрытие iframe плагина, то есть снятие с экрана, автоматически резолвит все повисшие confirm'ы этого плагина как
{ confirmed: false }. - Esc / клик по крестику —
{ confirmed: false }.
Навигация
Программное открытие ссылок
uiApi.navigate({
path: `/path`,
params: { a: "testParam" },
options: { newTab: true },
});
type NavigateRequest = {
path: string;
params?: QueryParams;
options?: {
newTab?: boolean;
};
};
Обработка клика на ссылке
-
Относительные ссылки и ссылки домена плагина => открываются в плагине
-
Внешние => прокидываются в трекер через uiApi.navigate =>
ссылки на трекер => открываются в текущей вкладке или в новом табе в зависимости от target="_blank"
внешние => всегда в новом табе
trackerApi (TrackerApi)
Класс для вызова Tracker Public API через хост по контракту api.tracker.call. Доступ к эндпоинтам — через типизированное API v3.
Описание методов и форматов ответов: Common format.
Экспортируется singleton trackerApi.
v3
Объект с методами по HTTP: get, post, put, patch, delete. Ключи — пути эндпоинтов из OpenAPI (@weavix/tracker-api-types). При обращении по пути IDE показывает подсказки и JSDoc.
Примеры:
import { trackerApi } from "@weavix/sdk-core";
// GET
const data = await trackerApi.v3.get["/issues/{id}"]({
pathParams: { id: "QUEUE-123" },
queryParams: { expand: ["COMMENTS"] },
});
// POST
await trackerApi.v3.post["/v2/issues"]({
bodyParams: { queue: { key: "TASK" }, summary: "Новая задача" },
});
//POST with file
await trackerApi.v3.post["/attachments"]({
bodyParams: { filename },
file,
});
v3.get[path](payload)— GET;payload:pathParams, опциональноqueryParams.v3.post[path](payload)/ put / patch — вpayloadпередаетсяbodyParams(и при необходимостиpathParams,queryParams).v3.delete[path](payload)— DELETE;payload:pathParams, опциональноqueryParams.
Во все запросы через trackerApi.v3 в контракт уходит version: 'v3'.
storageApi
JSON-хранилище уровня организации, опосредованное хостом — storageApi.orgShared.get / storageApi.orgShared.patch. Полное описание методов, merge-семантики patch, версионирования и кодов ошибок — в разделе Хранилище данных.
import { storageApi } from "@weavix/sdk-core";
const record = await storageApi.orgShared.get("settings");
await storageApi.orgShared.patch({
bucket: "settings",
data: { theme: "dark" },
});
hostApi.externalApi*
Методы для обращения к внешним (не Tracker) HTTP API через прокси хоста с поддержкой OAuth-авторизации.
Политика безопасности: прямые HTTP-запросы из плагина (
fetch,XMLHttpRequestи т.п.) запрещены — браузер заблокирует их из-за CSP и политики iframe. Все обращения к внешним API обязаны идти черезhostApi.externalApiCall().
Разрешение в манифесте
Добавьте в manifest.json секцию permissions.external с перечнем разрешенных доменов:
{
"permissions": {
"external": [
{
"domain": "api.example.com",
"authorization": {
"type": "oauth",
"scopes": ["read", "write"],
"contextTypes": ["user"]
}
},
{
"domain": "cdn.example.com"
}
]
}
}
Поле authorization опционально — его можно опустить для доменов, не требующих авторизации, например для публичных CDN. Тип "token" используется для API-ключей и других не-OAuth токенов.
externalApiCall()
Выполняет HTTP-запрос к внешнему API через прокси платформы. URL должен относиться к домену, разрешенному в permissions.external. Заголовки авторизации подставляет хост.
Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
url |
string |
— | Полный URL запроса (обязательный) |
method |
'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' |
— | HTTP-метод (обязательный) |
headers |
Record<string, string> |
— | Дополнительные заголовки |
body |
Record<string, unknown> |
— | Тело запроса |
timeoutMs |
number |
— | Таймаут запроса в миллисекундах |
contextType |
'user' | 'organization' |
— | Контекст учетных данных для прокси |
Returns: Promise<{ status: number; headers?: Record<string, string>; body?: Record<string, unknown> }>
При ошибке прокси-запроса бросает PluginActionError с кодом EXTERNAL_API_CALL_ERROR (1013). Детали — в e.errorData.
import {
hostApi,
PluginActionError,
EXTERNAL_API_CALL_ERROR,
} from "@weavix/sdk-core";
// GET
const { status, body } = await hostApi.externalApiCall({
url: "https://api.example.com/v1/items",
method: "GET",
contextType: "user",
});
// POST с телом и таймаутом
const result = await hostApi.externalApiCall({
url: "https://api.example.com/v1/items",
method: "POST",
headers: { "Content-Type": "application/json" },
body: { name: "New item", value: 42 },
contextType: "organization",
timeoutMs: 10000,
});
// Обработка ошибок
try {
await hostApi.externalApiCall({
url: "https://api.example.com/data",
method: "GET",
});
} catch (e) {
if (e instanceof PluginActionError && e.code === EXTERNAL_API_CALL_ERROR) {
console.error("Proxy error:", e.errorData);
}
}
externalApiAuthCheckAndRequest()
Комбинирует проверку статуса авторизации и запрос credentials только для неаутентифицированных доменов. Если все домены уже аутентифицированы — сразу возвращает { success: true } без диалога.
Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
domains |
string[] |
все домены плагина | Домены для проверки |
contextType |
'user' | 'organization' |
— | Тип контекста учетных данных |
Returns: Promise<{ success: boolean }> — false, если пользователь закрыл диалог или истек таймаут (~5 минут).
const { success } = await hostApi.externalApiAuthCheckAndRequest({
domains: ["api.example.com"],
contextType: "user",
});
if (!success) return;
externalApiAuthGetStatus()
Возвращает статус авторизации по доменам.
Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
domains |
string[] |
все домены плагина | Домены для проверки |
contextType |
'user' | 'organization' |
— | Тип контекста учетных данных |
Returns: Promise<{ domains: Array<{ domain: string; contextType: AuthContextType; authenticated: boolean }> }>
const { domains } = await hostApi.externalApiAuthGetStatus({
domains: ["api.example.com"],
contextType: "user",
});
const isAuthed = domains.every((d) => d.authenticated);
externalApiAuthRequest()
Показывает пользователю диалог ввода учетных данных для указанных доменов. При успешном подтверждении хост сохраняет credentials.
Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
domains |
ExternalApiDomainInfo[] |
— | Домены (обязательно, минимум один) |
ExternalApiDomainInfo:
| Поле | Тип | Описание |
|---|---|---|
domain |
string |
Домен из манифеста |
instructions |
`string | { en?: string; ru?: string }` |
Returns: Promise<{ success: boolean }> — false, если пользователь закрыл диалог.
await hostApi.externalApiAuthRequest({
domains: [
{
domain: "api.example.com",
instructions: { ru: "Войдите в Example", en: "Sign in to Example" },
},
],
});
externalApiAuthRevoke()
Отзывает сохраненную авторизацию для указанных доменов.
Parameters:
| Параметр | Тип | По умолчанию | Описание |
|---|---|---|---|
domains |
string[] |
— | Домены для отзыва (обязательно, минимум один) |
contextType |
'user' | 'organization' |
— | Тип контекста учетных данных |
Returns: Promise<{ success: boolean }>
await hostApi.externalApiAuthRevoke({
domains: ["api.example.com"],
contextType: "user",
});
Types
TrackerApiInitOptions
Опции при создании экземпляра TrackerApi, если используется не singleton. Сейчас из core экспортируется только trackerApi, опции не передаются.
interface TrackerApiInitOptions {
apiVersion?: string;
}
TrackerApiCallOptions
Параметры вызова эндпоинта в v3: pathParams, queryParams, bodyParams.
interface TrackerApiCallOptions {
pathParams?: Record<string, string>;
queryParams?: Record<string, unknown>;
bodyParams?: Record<string, unknown>;
}
TrackerApiV3
Тип объекта trackerApi.v3: методы get/post/put/patch/delete с типизированными путями из @weavix/tracker-api-types.
Theme
Тип темы оформления хоста.
type Theme = "light" | "light-hc" | "dark" | "dark-hc" | "system";
SlotContextMap
Маппинг имен слотов на типы полного контекста (level: 'full'). Например, слот issue.action дает контекст типа Issue. Типы контекста — Issue и другие — задаются пакетом @weavix/tracker-api-types.
При level: 'basic' вместо полного объекта сущности возвращается BasicContext:
type BasicContext = {
/** Идентификатор текущей сущности */
entityId: string;
/** Дополнительная базовая информация.
* Например, для комментария содержит идентификатор родительского тикета. */
entityMeta?: Record<string, string>;
};
// Базовый контекст: только entityId и entityMeta
const basicContext = await hostApi.getContext("basic");
// basicContext.entityId — идентификатор сущности
// Полный контекст: для слота 'issue.action' вернет Issue
// Требует contextLevel: 'full' в manifest.json
const fullContext = await hostApi.getContext("full");
ContentSizeUpdateRequest
Запрос на изменение размера контента плагина.
type ContentSizeUpdateRequest = { height?: number };
HostInitOptions
Опции инициализации хоста, передаются в hostApi.init().
interface HostInitOptions {
/** Авто-ресайз по контенту, по умолчанию true */
autoResize?: boolean;
}
Коды ошибок API
При вызовах методов хост может вернуть ошибку с кодом. Константы экспортируются из пакета:
import {
EXTERNAL_API_CALL_ERROR,
METHOD_NOT_SUPPORTED,
MISSING_REQUIRED_SCOPE,
PLUGIN_ID_IS_NOT_CORRECT,
PLUGIN_ID_OR_SLOT_NOT_PROVIDED,
UNKNOWN_ERROR,
VALIDATION_ERROR,
} from "@weavix/sdk-core";
| Константа | Код | Описание |
|---|---|---|
PLUGIN_ID_OR_SLOT_NOT_PROVIDED |
1000 | Не переданы обязательные параметры инициализации плагина. |
PLUGIN_ID_IS_NOT_CORRECT |
1001 | Неверный или несовпадающий pluginId. |
VALIDATION_ERROR |
1002 | Ошибка валидации запроса. |
METHOD_NOT_SUPPORTED |
1003 | Метод не поддерживается. |
MISSING_REQUIRED_SCOPE |
1004 | Недостаточно прав (scope). |
EXTERNAL_API_CALL_ERROR |
1013 | Ошибка при выполнении HTTP-запроса через hostApi.externalApiCall(). |
UNKNOWN_ERROR |
6666 | Неизвестная ошибка. |
Utils
getLocalizedString()
Возвращает локализованную строку по коду языка. Тип LocalizedString экспортируется из @weavix/tracker-api-types, реэкспортируется из core.
function getLocalizedString(
value: LocalizedString,
language: string,
fallbackLanguage?: string,
): string;
getField()
Извлекает значение из объекта по точечному пути (dot notation).
function getField<T = unknown>(
obj: Record<string, unknown>,
path: string,
defaultValue?: T,
): T | undefined;
Handlers
Экспортируются getHandler, setHandler, типы HandlerFunction, Handlers, HttpMethod — для регистрации обработчиков запросов со стороны хоста. См. контракт и слоты.
Complete Example
import {
hostApi,
trackerApi,
getField,
type Theme,
} from "@weavix/sdk-core";
// Инициализация обычно выполняется в TrackerPluginProvider (react)
hostApi.init({ autoResize: true });
const theme: Theme = await hostApi.getTheme();
const language = await hostApi.getLanguage();
const context = await hostApi.getContext();
// Вызов Tracker API v3 (в payload уходит version: 'v3')
const issue = await trackerApi.v3.get["/issues/{id}"]({
pathParams: { id: "KEY-1" },
queryParams: { expand: ["COMMENTS"] },
});
const summary = getField<string>(issue, "summary", "Без названия");
await hostApi.notifyReady();
Типы запросов/ответов эндпоинтов (Issue, типы для создания задач, очередей и т.д.) задаются пакетом @weavix/tracker-api-types.