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;
    };
};

Обработка клика на ссылке

  1. Относительные ссылки и ссылки домена плагина => открываются в плагине

  2. Внешние => прокидываются в трекер через 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.

Предыдущая
Следующая