Перейти к содержанию

Объекты и типы JavaScript API

Модуль 0.133.0 · интерфейс 0.103.0 · Agent API 1.23 · редакция документации 1.3.

В архиве TypeScript находятся определения API этой версии: поля, параметры, типы и ограничения. Архив служит справочником; для запуска расширения используйте библиотеки из SDK.

Как выбрать нужный объект

Объект Назначение
GlitPageAgentApi Работа с документами через window.GLIT.wysiwyg.agent.v1
AgentBlockSpec Описание нового блока для вставки
AgentBlockSnapshot Состояние существующего блока, полученное при чтении
AgentDocumentSnapshot Состояние документа и его версия в редакторе
AgentApplyRequest Операции изменения с ожидаемой версией документа
AgentApplySavedResult Результат изменения, подтверждённого серверным сохранением
AgentExtensionCapabilities Доступные типы расширений и команды
WysiwygRuntimeConfigV1 Настройки интерфейса редактора
BrowserExtensionConfig Разрешённые расширения и файлы для браузера
PublicExtensionConfig Расширения для опубликованной страницы

Идентификаторы и версии

contentUid идентифицирует документ, а blockUid — блок внутри него. Ключ Lexical NodeKey существует только в текущем экземпляре редактора.

Метод inspect() возвращает editorVersion и дерево blocks. Эту версию передавайте в запрос изменения, чтобы не затереть более новое состояние. serverVersion относится к сохранению на сервере и editorVersion не заменяет.

AgentBlockSpec описывает новый блок, а AgentBlockSnapshot — уже прочитанное состояние. Запрос на изменение собирайте из полей нужной операции. Снимок целиком таким запросом не отправляйте.

Элемент редактора

Элемент <glit-wysiwyg> даёт методы isAgentReady, inspectAgentDocument, applyAgentOperations, getAgentExtensions, flushPendingUpdate, replaceContent, а также методы шаблонов и режимов экрана. Событие update передаёт HTML и JSON строками. Дальше эти строки сохраняет само приложение.

В runtime-config задаются schemaVersion: 1, варианты кнопок, шрифты, основные цвета, режимы экрана, карта классов и доступные функции. Для темы заполните также атрибут class-map: он нужен даже при наличии classMap в runtime-config.

В extension-config передаются manifestVersion: 1, digest и extensions. Получите эти данные из PHP-реестра: он вычислит digest и подставит URL и SHA-256 файлов для браузера. Закрытые серверные пути в конфигурацию не входят.

Состав архива

Файл контракта Типы и интерфейсы
declarative-blocks.ts DeclarativeBlock
declarative-data.ts DeclarativeScalar, DeclarativeField, DeclarativeDataSchema
editor-element.ts BitrixEditorReadyParams, GlitWysiwygElement, GlitWysiwygPersistenceStatus, GlitWysiwygRecoverySnapshotDetail, GlitWysiwygPreviewRequestDetail, GlitWysiwygUpdateDetail
entity-selection.ts EntitySelection
extension-agent.ts AgentExtensionCapabilities, AgentRuntimeDocument, AgentUpdateExtensionData, AgentInsertExtensionBlock, AgentStructureExtensionBlock, AgentNativeCommandDescriptor, AgentRunExtensionCommand, AgentExtensionCommandResult, AgentInsertRuntimeTemplate
page-agent-tools.ts PageAgentCoreWebMcpTool, PageAgentBitrixWebMcpTool
page-agent.ts AgentTypographyProperty, AgentTextFormat, AgentTypography, AgentTextFormats, AgentBlockType, AgentReadOnlyBlockType, AgentBlockFormat, AgentFilterStyles, AgentBlockStyles, AgentResponsiveStyles, AgentResponsiveHidden, AgentResponsiveData, AgentResponsiveVariant, AgentResponsivePreview, AgentMediaType, AgentMediaCollection, AgentMediaItem, AgentMediaPage, AgentInlineSpec, AgentInlineOrderItem, AgentBlockSpec, AgentOperation, AgentApplyRequest, AgentBlockSnapshot, AgentDocumentSnapshot, AgentApplyResult, AgentTemplateKind, AgentTemplateSummary, AgentContentTemplate, AgentListTemplatesInput, AgentInsertTemplateRequest, LexicalAgentBridge, AgentChangeAuthorSummary, AgentRevisionSummary, AgentHistoryPage, AgentBlockCatalogItem, AgentBlockCatalogPage, AgentRevisionChange, AgentRevisionComparison, AgentRestoreResult, AgentApplySavedResult, AgentPreviewResult, GlitPageAgentApi
public-extensions.ts PublicExtension, PublicExtensionConfig
runtime-config.ts ButtonVariantDefinition, FontFamilyDefinition, PrimaryColorDefinition, ClassMapDefinition, ResponsiveVariantDefinition, WysiwygRuntimeConfigV1
runtime-extensions.ts RuntimeExtensionStatus, ExtensionAsset, BrowserExtension, BrowserExtensionConfig
runtime-template-manifest.ts RuntimeTemplateManifest
runtime-template.ts RuntimeTemplateJson, RuntimeTemplateNode, RuntimeTemplateDocument
native-runtime.ts NativeExtensionHost, NativeEditorContext, NativeInsertDialogProps, NativePaletteItem, NativePropertiesProps, NativePropertiesDefinition, NativeToolbarAction, NativeAgentCommand, NativeTemplateCodec, NativeExtensionInstance

Определения типов

Для каждого типа приведён пример, затем его определение. Примеры используют общие учебные данные из предыдущих разделов. Идентификаторы, версии и хеши в ответах условные: в рабочем коде получайте их через API. Аннотации TypeScript нужны для проверки типов; они не входят в JSON. Полные определения и связанные типы находятся в архиве.

Знак ? после имени поля означает, что поле необязательно. readonly значит, что через этот тип поле менять нельзя. Запись 'loading' | 'ready' | 'error' — это одно из перечисленных значений.

GlitPageAgentApi

Получение API и чтение одного открытого документа. contentUid берётся из списка редакторов, а не придумывается приложением.

TypeScript
// API уже установлен интеграцией на текущей странице.
const api = window.GLIT.wysiwyg.agent.v1;
const editor = api.listEditors().find(item => item.ready);

if (!editor) {
    throw new Error('Нет редактора, готового к работе');
}

// Для нескольких открытых документов выберите нужный contentUid явно.
const snapshot = api.inspect({contentUid: editor.contentUid});
console.log(snapshot.editorVersion, snapshot.blocks);

Определение типа:

TypeScript
export type GlitPageAgentApi = {
    readonly apiVersion: typeof AGENT_API_VERSION;
    apply(input: AgentApplyRequest & {contentUid: string}): Promise<AgentApplySavedResult>;
    capabilities(input?: {contentUid: string}): {
        runtimeExtensions: AgentExtensionCapabilities | null;
        blockTypes: AgentBlockSpec['type'][];
        excludedBlockTypes: [];
        inlineTypes: ['link', 'text'];
        mediaTypes: AgentMediaType[];
        maxOperationsPerApply: number;
        operations: AgentOperation['op'][];
        readOnlyBlockTypes: AgentReadOnlyBlockType[];
        responsiveDataBlockTypes: ['layout-container', 'layout-item', 'video', 'slider'];
        responsiveBaseVariantCode: string;
        responsiveVariants: AgentResponsiveVariant[];
        rootBlockUid: typeof ROOT_BLOCK_UID;
        supportsBlockData: true;
        supportsContentTemplates: true;
        supportsParagraphInlineOrder: true;
        supportsMediaLibrary: true;
        supportsResponsiveBlockData: true;
        supportsResponsiveLayout: true;
        supportsResponsiveStyles: true;
        supportsResponsiveVisibility: true;
        supportsRevisionComparison: true;
        supportsRevisionHistory: true;
        supportsBlockRevisionHistory: true;
        supportsBlockCatalog: true;
        supportsBlockRestore: true;
        supportsRevisionChangesOnly: true;
        supportsSafeStyles: true;
        supportsCustomClasses: true;
        supportsStableImageAspectRatio: true;
        supportsTypography: true;
        templateKinds: AgentTemplateKind[];
        templateSources: ['registered'];
        textFormats: AgentTextFormat[];
        typographyProperties: AgentTypographyProperty[];
    };
    browseMedia(input: {
        collectionId?: number;
        mediaType: AgentMediaType;
        page?: number;
        pageSize?: number;
        query?: string;
    }): Promise<AgentMediaPage>;
    checkpoint(input: {comment?: string; contentUid: string}): Promise<AgentRevisionSummary>;
    compareRevisions(input: {
        contentUid: string;
        fromRevisionId: number;
        toRevisionId: number;
    }): Promise<AgentRevisionComparison>;
    getTemplate(input: {contentUid: string; id: string; providerId: string}): AgentContentTemplate;
    inspect(input: {contentUid: string}): AgentDocumentSnapshot;
    insertTemplate(input: AgentInsertTemplateRequest & {contentUid: string}): Promise<AgentApplySavedResult>;
    listEditors(): Array<{contentUid: string; ready: boolean}>;
    listBlockCatalog(input: {contentUid: string; cursor?: string; query?: string}): Promise<AgentBlockCatalogPage>;
    listHistory(input: {
        beforeId?: number;
        blockUid?: string;
        changesOnly?: boolean;
        contentUid: string;
    }): Promise<AgentHistoryPage>;
    listTemplates(input: AgentListTemplatesInput & {contentUid: string}): AgentTemplateSummary[];
    preview(input: {contentUid: string}): Promise<AgentPreviewResult>;
    restoreRevision(input: {blockUid?: string; contentUid: string; revisionId: number}): Promise<AgentRestoreResult>;
    setResponsiveVariant(input: {contentUid: string; variantCode: string}): AgentResponsivePreview;
    setRevisionPinned(input: {contentUid: string; pinned: boolean; revisionId: number}): Promise<{id: number; pinned: boolean}>;
    uploadMedia(input: {
        collectionId: number;
        dataBase64: string;
        fileName: string;
        mediaType: AgentMediaType;
        mimeType?: string;
    }): Promise<AgentMediaItem>;
};

AgentBlockSpec

Первый объект создаёт обычный абзац. Второй создаёт заголовок второго уровня с отдельным оформлением. В AgentBlockSpec нет blockUid: его назначает редактор при вставке.

TypeScript
// Минимальный блок: обычный абзац.
const paragraph: AgentBlockSpec = {
    type: 'paragraph',
    text: 'Доставка по России',
};

// Тот же текст в заголовке: меняются тип, уровень и оформление.
const heading: AgentBlockSpec = {
    type: 'heading',
    headingLevel: 2,
    text: 'Доставка по России',
    typography: {
        color: '#0066ff',
        fontWeight: 700,
    },
    styles: {
        margin: {bottom: '24px'},
    },
};

Определение типа:

TypeScript
export type AgentBlockSpec = {
    inlineOrder?: AgentInlineOrderItem[];
    children?: AgentBlockSpec[];
    /** Space-separated CSS class tokens. Normalized on write (max 64 tokens, 128 chars each). */
    customClasses?: string;
    data?: Record<string, unknown>;
    format?: AgentBlockFormat;
    formats?: AgentTextFormats;
    headingLevel?: 1 | 2 | 3 | 4 | 5 | 6;
    inline?: AgentInlineSpec[];
    responsiveData?: AgentResponsiveData;
    responsiveStyles?: AgentResponsiveStyles;
    responsiveHidden?: AgentResponsiveHidden;
    styles?: AgentBlockStyles;
    text?: string;
    typography?: AgentTypography;
    type: AgentBlockType;
};

AgentBlockSnapshot

Пример прочитанного абзаца. В ответе уже есть стабильный blockUid, дочерние блоки и настройки для разных экранов. Пустые объекты означают, что отдельные значения не заданы.

TypeScript
// Учебный ответ inspect(); идентификатор назначен редактором.
const paragraphSnapshot: AgentBlockSnapshot = {
    blockUid: '11111111-1111-4111-8111-111111111111',
    type: 'paragraph',
    text: 'Доставка по России',
    children: [],
    customClasses: '',
    styles: {},
    responsiveData: {},
    responsiveStyles: {},
    responsiveHidden: {},
};

Определение типа:

TypeScript
export type AgentBlockSnapshot = {
    inlineOrder?: AgentInlineOrderItem[];
    blockUid: string;
    children: AgentBlockSnapshot[];
    customClasses: string;
    data?: Record<string, unknown>;
    format?: AgentBlockFormat;
    inline?: AgentInlineSpec[];
    responsiveData: AgentResponsiveData;
    responsiveStyles: AgentResponsiveStyles;
    responsiveHidden: AgentResponsiveHidden;
    styles: AgentBlockStyles;
    text: string;
    type: AgentBlockType;
};

AgentDocumentSnapshot

Документ содержит абзац из предыдущего примера. Число 7 — версия состояния редактора. В режиме телефона меняется activeVariantCode, а общая база остаётся desktop.

TypeScript
// Условные данные ответа; в рабочем коде получите их через inspect().
const documentSnapshot: AgentDocumentSnapshot = {
    apiVersion: '1.23',
    editorVersion: 7,
    blocks: [paragraphSnapshot],
    runtimeDocument: null,
    responsivePreview: {
        activeVariantCode: 'mobile',
        baseVariantCode: 'desktop',
        variants: [
            {
                code: 'desktop',
                label: 'Компьютер',
                icon: 'monitor',
                base: true,
                minWidth: null,
                maxWidth: null,
            },
            {
                code: 'mobile',
                label: 'Телефон',
                icon: 'smartphone',
                base: false,
                minWidth: null,
                maxWidth: 640,
            },
        ],
    },
};

Определение типа:

TypeScript
export type AgentDocumentSnapshot = {
    runtimeDocument?: AgentRuntimeDocument | null;
    apiVersion: typeof AGENT_API_VERSION;
    blocks: AgentBlockSnapshot[];
    editorVersion: number;
    responsivePreview: AgentResponsivePreview;
};

AgentApplyRequest

Первый запрос добавляет новый абзац. Второй меняет текст существующего. expectedEditorVersion нужно получать заново перед каждой операцией, а не постоянно передавать 7.

TypeScript
// Два альтернативных запроса для одного исходного состояния.
const insertRequest: AgentApplyRequest = {
    expectedEditorVersion: documentSnapshot.editorVersion,
    operations: [
        {
            op: 'insertBlock',
            block: paragraph,
            index: 0,
        },
    ],
};

const renameRequest: AgentApplyRequest = {
    expectedEditorVersion: documentSnapshot.editorVersion,
    operations: [
        {
            op: 'replaceText',
            blockUid: paragraphSnapshot.blockUid,
            text: 'Бесплатная доставка от 5 000 рублей',
        },
    ],
};

Определение типа:

TypeScript
export type AgentApplyRequest = {
    expectedEditorVersion?: number;
    operations: AgentOperation[];
};

AgentApplyResult

Результат операции на уровне редактора: новая версия состояния и список затронутых блоков. Этот объект сам по себе не подтверждает запись на сервер.

TypeScript
// Учебный результат замены текста из предыдущего примера.
const applyResult: AgentApplyResult = {
    ...documentSnapshot,
    editorVersion: 8,
    blocks: [
        {
            ...paragraphSnapshot,
            text: 'Бесплатная доставка от 5 000 рублей',
        },
    ],
    changedBlockUids: [paragraphSnapshot.blockUid],
};

Определение типа:

TypeScript
export type AgentApplyResult = AgentDocumentSnapshot & {
    extensionResult?: AgentExtensionCommandResult;
    changedBlockUids: string[];
};

AgentApplySavedResult

К результату редактирования добавлены подтверждение автосохранения, версия на сервере и автор. Версия 12 на сервере не обязана совпадать с версией 8 в редакторе.

TypeScript
// Такой ответ возвращает интеграция после успешного автосохранения.
const savedResult: AgentApplySavedResult = {
    ...applyResult,
    autosaved: true,
    serverVersion: 12,
    author: {
        id: 42,
        login: 'editor',
        displayName: 'Редактор сайта',
    },
};

Определение типа:

TypeScript
export type AgentApplySavedResult = AgentApplyResult & {
    author: AgentChangeAuthorSummary | null;
    autosaved: true;
    serverVersion: number;
};

AgentMediaItem

Изображение имеет адрес оригинала и отдельную миниатюру. id и collectionIds относятся к медиабиблиотеке. Для видео меняются MIME-тип и адрес файла; набор полей остаётся тем же.

TypeScript
// Условная запись медиабиблиотеки, не команда загрузки файла.
const mediaItem: AgentMediaItem = {
    id: 125,
    name: 'Офис',
    description: 'Вход в офис компании',
    mimeType: 'image/jpeg',
    fileSize: 184320,
    width: 1600,
    height: 900,
    src: '/upload/company/office.jpg',
    thumbnailSrc: '/upload/company/office-small.jpg',
    collectionIds: [3],
};

Определение типа:

TypeScript
export type AgentMediaItem = {
    collectionIds: number[];
    description: string;
    fileSize: number;
    height: number;
    id: number;
    mimeType: string;
    name: string;
    src: string;
    thumbnailSrc: string;
    width: number;
};

AgentMediaPage

Одна страница выдачи с одним изображением. Коллекция разрешает загрузку; total считает все найденные файлы, а items содержит только текущую страницу.

TypeScript
// Учебный результат browseMedia().
const mediaPage: AgentMediaPage = {
    mediaType: 'image',
    page: 1,
    pageCount: 1,
    pageSize: 20,
    total: 1,
    collections: [
        {
            id: 3,
            parentId: 0,
            name: 'Компания',
            canUpload: true,
        },
    ],
    items: [mediaItem],
};

Определение типа:

TypeScript
export type AgentMediaPage = {
    collections: AgentMediaCollection[];
    items: AgentMediaItem[];
    mediaType: AgentMediaType;
    page: number;
    pageCount: number;
    pageSize: number;
    total: number;
};

AgentRevisionSummary

Контрольная версия истории. id используется в запросах восстановления, number показывается пользователю. pinned отмечает закреплённую версию, а restoredFromRevisionId заполняется после восстановления.

TypeScript
// Учебная запись истории; хеш приведён только для показа формы ответа.
const revision: AgentRevisionSummary = {
    id: 501,
    number: 12,
    type: 'checkpoint',
    comment: 'Перед обновлением условий доставки',
    createdAt: '2026-09-28T12:00:00+03:00',
    createdBy: 42,
    author: {
        id: 42,
        login: 'editor',
        displayName: 'Редактор сайта',
    },
    contentHash: 'a'.repeat(64),
    sizeBytes: 2048,
    pinned: true,
    restoredFromRevisionId: null,
};

Определение типа:

TypeScript
export type AgentRevisionSummary = {
    author: AgentChangeAuthorSummary;
    comment: string;
    contentHash: string;
    createdAt: string;
    createdBy: number | null;
    id: number;
    number: number;
    pinned: boolean;
    restoredFromRevisionId: number | null;
    sizeBytes: number;
    type: string;
};

AgentExtensionCapabilities

Пример возможностей редактора с декларативным сообщением. В JavaScript-пакете вместо пустого nativeNodeTypes появятся типы узлов, а в nativeCommands — явно зарегистрированные команды. Настоящий digest берите из capabilities().

TypeScript
// Учебное описание возможностей, не конфигурация для ручной установки.
const extensionCapabilities: AgentExtensionCapabilities = {
    schemaVersion: 1,
    digest: 'a'.repeat(64),
    declarativeBlocks: [
        {
            extensionId: 'starter.notice',
            type: 'notice',
            label: 'Сообщение',
            schemaVersion: 1,
            kind: 'atomic',
            schema: {
                schemaVersion: 1,
                fields: {
                    title: {type: 'string', default: 'Сообщение', maxLength: 120},
                    text: {type: 'string', default: '', maxLength: 2048},
                    showText: {type: 'boolean', default: true},
                },
            },
            slots: [],
        },
    ],
    nativeNodeTypes: [],
    nativeTemplateNodeTypes: [],
    nativeCommands: [],
    toolbarActions: [],
    operations: ['insertExtensionBlock', 'updateExtensionData'],
};

Определение типа:

TypeScript
export type AgentExtensionCapabilities = {
    schemaVersion: 1;
    digest: string;
    declarativeBlocks: Array<{
        extensionId: string; type: string; label: string; schemaVersion: 1;
        kind: 'atomic' | 'container'; schema: DeclarativeDataSchema;
        slots: Array<{name: string; label: string}>;
    }>;
    nativeNodeTypes: string[];
    /** Available since API 1.20. Only these explicit commands may execute native code. */
    /** Types with explicit native template cloning codecs, since API 1.22. */
    nativeTemplateNodeTypes?: string[];
    nativeCommands?: AgentNativeCommandDescriptor[];
    toolbarActions: Array<{code: string; label: string; agentCallable: false}>;
    operations: Array<'updateExtensionData' | 'insertExtensionBlock' | 'moveExtensionBlock' | 'deleteExtensionBlock' | 'runExtensionCommand' | 'insertRuntimeTemplate'>;
};

AgentNativeCommandDescriptor

Команда учебного JavaScript-блока меняет подпись. Вход и выход имеют одинаковое поле label. Это описание доступной команды; её реализация находится в пакете расширения.

TypeScript
// Код состоит из идентификатора расширения и локального имени команды.
const renameCommand: AgentNativeCommandDescriptor = {
    code: 'native:starter.native/rename',
    label: 'Изменить подпись',
    nodeTypes: ['starter.native.notice'],
    inputSchema: {
        schemaVersion: 1,
        fields: {
            label: {type: 'string', maxLength: 120},
        },
    },
    outputSchema: {
        schemaVersion: 1,
        fields: {
            label: {type: 'string', maxLength: 120},
        },
    },
};

Определение типа:

TypeScript
export type AgentNativeCommandDescriptor = {
    code: string; label: string; nodeTypes: string[];
    inputSchema: DeclarativeDataSchema; outputSchema: DeclarativeDataSchema;
};

AgentInsertExtensionBlock

Операция вставляет сообщение в начало документа. data должна соответствовать схеме установленного блока. Поле expectedDigest здесь учебное; в реальном запросе возьмите его из текущих возможностей редактора.

TypeScript
// Объект операции; отправляйте его единственным элементом operations.
const insertNotice: AgentInsertExtensionBlock = {
    op: 'insertExtensionBlock',
    expectedDigest: extensionCapabilities.digest,
    extensionId: 'starter.notice',
    blockType: 'notice',
    schemaVersion: 1,
    data: {
        title: 'Доставка',
        text: 'Отправим заказ на следующий рабочий день',
        showText: true,
    },
    index: 0,
};

Определение типа:

TypeScript
export type AgentInsertExtensionBlock = {
    op: 'insertExtensionBlock';
    expectedDigest: string;
    extensionId: string;
    blockType: string;
    schemaVersion: 1;
    data: Record<string, import('./declarative-data').DeclarativeScalar>;
    parentBlockUid?: string;
    index?: number;
};

AgentStructureExtensionBlock

Первая операция перемещает существующий блок в начало документа. Вторая удаляет его. Это альтернативы: передавайте одну из них за вызов и получайте актуальную версию перед следующим вызовом.

TypeScript
// Идентификатор берётся из runtimeDocument.nodes, полученных через inspect().
const noticeUid = '22222222-2222-4222-8222-222222222222';

const moveNotice: AgentStructureExtensionBlock = {
    op: 'moveExtensionBlock',
    blockUid: noticeUid,
    expectedDigest: extensionCapabilities.digest,
    index: 0,
};

const deleteNotice: AgentStructureExtensionBlock = {
    op: 'deleteExtensionBlock',
    blockUid: noticeUid,
    expectedDigest: extensionCapabilities.digest,
};

Определение типа:

TypeScript
export type AgentStructureExtensionBlock =
    | {op: 'deleteExtensionBlock'; blockUid: string; expectedDigest: string}
    | {op: 'moveExtensionBlock'; blockUid: string; expectedDigest: string; parentBlockUid?: string; index?: number};

WysiwygRuntimeConfigV1

Конфигурация задаёт кнопку, шрифт, основной цвет и два размера экрана. Классы из примера должны быть определены в CSS сайта.

TypeScript
// Конфигурация интерфейса, сериализуемая в атрибут runtime-config.
const runtimeConfig: WysiwygRuntimeConfigV1 = {
    schemaVersion: 1,
    buttonVariants: {
        primary: {
            label: 'Основная',
            className: 'project-button-primary',
        },
    },
    classMap: {
        paragraph: 'project-paragraph',
    },
    fontFamilies: [
        {name: 'Arial', value: 'Arial, sans-serif'},
    ],
    primaryColors: [
        {
            code: 'brand',
            name: 'Фирменный синий',
            value: '#0066ff',
            cssVariable: '--glit-color-brand',
        },
    ],
    enabledElements: [],
    enabledFeatures: [],
    responsiveVariants: [
        {
            code: 'desktop',
            label: 'Компьютер',
            icon: 'monitor',
            minWidth: null,
            maxWidth: null,
        },
        {
            code: 'mobile',
            label: 'Телефон',
            icon: 'smartphone',
            minWidth: null,
            maxWidth: 640,
        },
    ],
};

Определение типа:

TypeScript
export type WysiwygRuntimeConfigV1 = {
    buttonVariants: Record<string, ButtonVariantDefinition>;
    classMap: ClassMapDefinition;
    enabledElements: string[];
    enabledFeatures: string[];
    fontFamilies: FontFamilyDefinition[];
    primaryColors: PrimaryColorDefinition[];
    responsiveVariants?: ResponsiveVariantDefinition[];
    schemaVersion: typeof WYSIWYG_CONFIG_SCHEMA_VERSION;
};

BrowserExtension

Один декларативный пакет в конфигурации браузера. Здесь используются URL, а в серверном манифесте на странице Runtime SDK — относительные имена file. Хеш ниже условный: рабочую конфигурацию формирует PHP-реестр.

TypeScript
// Пример результата browserConfig(), не исходный манифест пакета.
const browserExtension: BrowserExtension = {
    manifestVersion: 1,
    id: 'starter.notice',
    version: '1.1.0',
    sdkVersion: 1,
    kind: 'declarative',
    dependencies: {},
    assets: {
        descriptor: {
            url: '/bitrix/js/project/editor/starter.notice/1.1.0/notice.json',
            sha256: 'a'.repeat(64),
        },
    },
};

Определение типа:

TypeScript
export type BrowserExtension = Readonly<{
    manifestVersion: 1; id: string; version: string; sdkVersion: 1; nativeAbi?: string; kind?: 'native' | 'declarative';
    dependencies: Readonly<Record<string, string>>;
    assets: Readonly<{editor?: ExtensionAsset; descriptor?: ExtensionAsset; public?: ExtensionAsset; style?: ExtensionAsset}>;
}>;

BrowserExtensionConfig

Обёртка объединяет пакеты для одного редактора. digest относится ко всему набору. Конфигурация без расширений содержит пустой массив extensions, но её digest тоже вычисляет сервер.

TypeScript
// Учебный результат ExtensionSnapshot::browserConfig().
const browserConfig: BrowserExtensionConfig = {
    manifestVersion: 1,
    digest: 'b'.repeat(64),
    extensions: [browserExtension],
};

Определение типа:

TypeScript
export type BrowserExtensionConfig = Readonly<{
    manifestVersion: 1; digest: string; extensions: readonly BrowserExtension[];
}>;

RuntimeExtensionStatus

Во время загрузки достаточно state. При успехе появляется digest, при ошибке — пояснение. Событие сообщает состояние, а не разрешает загрузку пакета.

TypeScript
// Три возможных сообщения об одном процессе загрузки.
const loadingStatus: RuntimeExtensionStatus = {
    state: 'loading',
};

const readyStatus: RuntimeExtensionStatus = {
    state: 'ready',
    digest: browserConfig.digest,
};

const errorStatus: RuntimeExtensionStatus = {
    state: 'error',
    message: 'Не удалось загрузить файл расширения',
};

Определение типа:

TypeScript
export type RuntimeExtensionStatus = {state: 'loading' | 'ready' | 'error'; digest?: string; message?: string};

PublicExtension

Пакет для страницы посетителя содержит только публичный JavaScript и CSS. В нём нет редакторской формы и серверного JavaScript. Вариант без интерактивности может содержать только style.

TypeScript
// Учебные URL и контрольная сумма; в рабочем коде их выдаёт сервер.
const publicExtension: PublicExtension = {
    id: 'starter.native',
    version: '1.4.0',
    dependencies: {},
    assets: {
        public: {
            url: '/bitrix/js/project/editor/starter.native/1.4.0/public.mjs',
            sha256: 'c'.repeat(64),
        },
    },
};

Определение типа:

TypeScript
export type PublicExtension = Readonly<{
    id: string; version: string; dependencies: Readonly<Record<string, string>>;
    assets: Readonly<{public?: ExtensionAsset; style?: ExtensionAsset}>;
}>;

PublicExtensionConfig

Обёртка предназначена для публичной страницы. Её отличает publicVersion; редактор использует manifestVersion. Разрешение на публичные скрипты сервер проверяет отдельно.

TypeScript
// Учебный результат ExtensionSnapshot::publicConfig().
const publicConfig: PublicExtensionConfig = {
    publicVersion: 1,
    digest: 'd'.repeat(64),
    extensions: [publicExtension],
};

Определение типа:

TypeScript
export type PublicExtensionConfig = Readonly<{publicVersion: 1; digest: string; extensions: readonly PublicExtension[]}>;

Схемы данных узлов описывают параметры блоков. Runtime SDK объясняет подключение расширений, а Page Agent API — порядок выполнения операций.