Внешние API

Плагин работает в iframe с жесткой политикой CSP — прямые fetch/XMLHttpRequest к внешним сервисам браузер заблокирует. Все HTTP-запросы наружу обязаны идти через hostApi.externalApiCall(): плагин передает параметры запроса через мост, хост выполняет его на своей стороне и возвращает результат.

Разрешение в манифесте

Добавьте в manifest.json секцию permissions.external с перечнем разрешенных доменов:

{
    "permissions": {
        "external": [
            {
                "domain": "api.example.com",
                "authorization": {
                    "type": "oauth",
                    "scopes": ["read", "write"],
                    "contextTypes": ["user"]
                }
            }
        ]
    }
}

Поле authorization опционально — его можно опустить для доменов без авторизации.

Базовое использование

Типичный сценарий — проверить авторизацию, при необходимости запросить ее у пользователя, затем вызвать API:

import {
    hostApi,
    PluginActionError,
    EXTERNAL_API_CALL_ERROR,
} from "@weavix/sdk-react";

async function fetchItems() {
    // Проверить авторизацию и показать диалог, если нужно
    const { success } = await hostApi.externalApiAuthCheckAndRequest({
        domains: ["api.example.com"],
        contextType: "user",
    });
    if (!success) {
        // Пользователь закрыл диалог или истек таймаут
        return;
    }

    // Вызвать внешний API через прокси хоста
    const { status, body } = await hostApi.externalApiCall({
        url: "https://api.example.com/v1/items",
        method: "GET",
        contextType: "user",
    });
    // status — HTTP-статус ответа
    // body   — тело ответа (Record<string, unknown>)
}

POST с телом и таймаутом:

const { status, body } = 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,
});

Обработка ошибок

При сетевой ошибке или ответе с ошибочным статусом хост бросает PluginActionError с кодом EXTERNAL_API_CALL_ERROR (1013). Детали — в e.errorData:

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 проверяет авторизацию и при необходимости показывает диалог в одном вызове, см. пример выше.

Ручное управление. Если нужен более тонкий контроль — используйте отдельные методы:

// Проверить статус по доменам
const { domains } = await hostApi.externalApiAuthGetStatus({
    domains: ["api.example.com"],
    contextType: "user",
});
const isAuthed = domains.every((d) => d.authenticated);

// Показать диалог авторизации с подсказкой
if (!isAuthed) {
    await hostApi.externalApiAuthRequest({
        domains: [
            {
                domain: "api.example.com",
                instructions: {
                    ru: "Войдите в Example",
                    en: "Sign in to Example",
                },
            },
        ],
    });
}

// Отозвать сохраненные учетные данные
await hostApi.externalApiAuthRevoke({
    domains: ["api.example.com"],
    contextType: "user",
});

Подробнее о методах — в разделе hostApi.externalApi*.