npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@emailmaker/emailmaker

v1.1.103

Published

<p align="left"> <a href="https://emailmaker.ru/" target="blank"><img src="https://emcdn.ru/389992/240402_17_0uOwHpL.png" width="500" alt="EmailMaker" /></a> </p>

Readme

Установка

Установите пакет из npm:

npm install @emailmaker/emailmaker

Полезные ссылки

Добавьте плагин сборки EmailMaker в конфигурацию приложения (он копирует статику пакета и задаёт __emailmaker__.publicPath для загрузки чанков). Без Webpack/Vite-плагина вручную нужно обеспечить корректный базовый путь к бандлу.

Плагины к редактору

Редактор расширяется плагинами: они добавляют панели, блоки и свои настройки. Плагин — отдельный проект; заготовку делает CLI (npx @emailmaker/cli --kind plugin), а его сборка ведётся через PluginDev из этого же пакета.

Главное, что стоит знать заранее: плагин и редактор обязаны работать на одном экземпляре React, antd и ui-kit — иначе интерфейс падает при отрисовке панели плагина. PluginDev обеспечивает это сам, а плагин сборки хоста предупредит, если в сборку попала вторая копия.

Плагины на глобалах при ESM-входе: compatGlobals

Плагин, собранный под глобалы (UMD-скрипт по адресу, дескриптор с type: 'umd' или resolve: 'registry'), берёт antd, иконки и ui-kit из window.__emailmaker__.modules. В ESM-входе этот слой совместимости по умолчанию выключен: он целиком везёт antd и каталог иконок, и платить за него должен только тот, у кого такие плагины есть. Без слоя плагин падает с ошибкой `antd` is not available: the compatibility layer for global plugins is not enabled; в её конце — Requested by: <адрес> скрипта, который обратился к имени. modules.UiKit и modules.UiKitIcons без слоя не бросают, а отдают undefined и пишут ту же причину в консоль один раз: прежние плагины проверяли их наличием.

Включите слой одним из способов:

  • опцией плагина сборщика — compatGlobals: true (см. «Для сборщика Webpack» / «Для сборщика Vite»);
  • или явным импортом до создания редактора: import '@emailmaker/emailmaker/compat-globals';.

Слой попадает в стартовый бандл. В Webpack опция подключает его к каждой точке входа, даже если редактор у вас грузится лениво; в Vite — вместе с модулем редактора. В UMD-сборке слой не нужен: глобалы там есть всегда.

Чеклист для агентов и автоматизации

Используйте таблицу при генерации кода интеграции или ревью. Источник типов — emailmaker.d.ts в пакете (ExportedApi); не подставляйте вымышленные поля API.

Подробнее о том, как в .d.ts сливаются ExportedApi.Options / Instance, что такое AppEvent и SaveEventPayload, и как читать исключения (handleSubjectChanged и др.), — в типах самого пакета: они лежат рядом с кодом и открываются подсказками IDE.

| Правило | Детали | | --- | --- | | init | Обязательно content. Сигнатура: init(options) → Promise<Instance>. | | Namespace vs instance | У модуля emailmaker — в основном init (+ именованные ESM-экспорты). setConfig, show, save, destroy — у экземпляра после init. | | Повтор на том же DOM | Повторный init на тот же узел отдаёт тот же объект и применяет опции, как setConfig. Если прежний ещё стартует — его промис отклоняется AbortError, успешен второй. destroy() через любую ссылку уничтожает редактор. Свой объект на вызов — опция ownership: 'counted'. | | События | instance.handle*(…) обычно возвращает отписку. handleSubjectChanged / handlePreheaderChanged — другая сигнатура (см. типы). | | Async | Колбэки и getAuthToken могут быть async; ошибки — через handleError или свою логику. | | Сборка | Без штатного плагина Webpack/Vite задайте publicPath (__emailmaker__). Бандл крупный (React, Monaco и др.). | | Авторизация | getAuthToken; client_secret только на сервере. | | Файловый менеджер | storageProvider, config.imageCenterFileManagerView: true, при необходимости секция config.fileManager (ExportedApi.FileManagerOptions). Контракт StorageProvider объёмен — сверяйтесь с типами. | | baseUrl | Origin API без суффикса /wp-json (напр. https://api.emailmaker.ru или https://app.emailmaker.ru/api); SDK добавляет /wp-json сам. | | standaloneKey | Ключ замкнутого контура: файлы и внешние адреса идут через ваши обработчики, а не через наш бэкенд. Описан в документации по прокси ресурсов. | | commonStyles | Опционально на init / reset: объект стилей контента (частичный merge с COMMON_STYLES). |

Готовый пример страницы-хоста создаёт CLI: npx @emailmaker/cli --kind demo-stand.

Для сборщика Webpack

Импортируйте класс и передайте его в plugins под тем же именем:

const EmailmakerWebpackPlugin = require('@emailmaker/emailmaker/webpack');

module.exports = {
  plugins: [
    new EmailmakerWebpackPlugin({
      // По желанию: outputFolder, modulesPath, publicPath — см. пакет.
      // compatGlobals: true — только если подключаете плагины на глобалах (см. выше).
    }),
  ],
};

Для сборщика Vite

Импорт только из scoped-пакета:

import { defineConfig } from 'vite';
import emailmakerVite from '@emailmaker/emailmaker/vite';

export default defineConfig({
  plugins: [
    emailmakerVite({
      // По желанию: outputFolder, modulesPath, publicPath — см. пакет.
      // compatGlobals: true — только если подключаете плагины на глобалах (см. выше).
    }),
  ],
});

__emailmaker__

Плагины Webpack/Vite добавляют в бандл объект __emailmaker__ = { publicPath: '...' } с базовым URL к чанкам пакета. Вручную менять его обычно не нужно; без штатного плагина задайте publicPath самостоятельно так, чтобы загрузчик нашёл собранные emailmaker.js / emailmaker-esm.js.

Имя класса Webpack-плагина строится из имени приложения в package.json (для @emailmaker/emailmaker это EmailmakerWebpackPlugin).

Инициализация

Импортируйте плагин в коде приложения:

import * as emailmaker from '@emailmaker/emailmaker';

У init обязательное поле — content (HTML-строка или объект письма / шаблона). После успешной инициализации методы setConfig, updateConfig, show, save и др. доступны у экземпляра, возвращённого из init (не у объекта emailmaker).

Частые поля верхнего уровня — в таблице; детали конфигурации и содержимого см. ниже в разделе «Конфигурация».

| Поле | Назначение | | --- | --- | | getAuthToken | OAuth-колбэк: возвращает access token. | | element | Контейнер монтирования (селектор, узел или фрагмент). | | hidden | Работать в этом контейнере, но не показывать интерфейс (см. «Скрытый старт»). | | content | Обязательно: HTML-строка или объект письма/шаблона. | | config | Настройки UI редактора (ExportedApi.Config). | | project | Идентификатор проекта в вашей системе / в EmailMaker. | | baseUrl | Origin API без /wp-json (см. AppInitMixin.Options). | | storageProvider | Реализация StorageProvider для файлового менеджера. | | standaloneKey | Замкнутый контур: прокси файлов и адресов через instance.handleFileProxy / handleUrlProxy. Подробности — в документации по прокси ресурсов. | | commonStyles | Объект стилей контента (частичный merge с COMMON_STYLES). |

  • getAuthToken — функция (user?, project?, prevToken?) => string | Promise<string>, возвращающая OAuth access token. client_secret получайте только на сервере.

Именованные экспорты в ESM-сборке (emailmaker-esm.js):

import { init, parseAMP, COMMON_STYLES, version, helpers, errors } from '@emailmaker/emailmaker';

| Экспорт | Назначение | | --- | --- | | init | То же, что emailmaker.init, с ленивой подгрузкой ядра (Promise<Instance>). | | parseAMP | Разбор AMP: вход — строка или { code }, результат ParsedAMP (html / ampHtml и т.д.). | | COMMON_STYLES | Дефолтный пресет стилей контента текущей сборки EmailMaker. Для init({ commonStyles: { ...COMMON_STYLES, … } }). Значения и их описания видны в типах пакета. | | version | Строка версии сборки. | | helpers | Вспомогательные утилиты (например, соответствие HTTP-статусов кодам ошибок). | | errors | Ошибки API, в т.ч. errors.FileManagerApiError для контракта с файловым менеджером. |

Получение OAuth токена на бэкенде

curl --location 'https://api.emailmaker.ru/oauth/token' \
--header 'Content-Type: application/x-www-form-urlencoded' \
--data-urlencode 'client_id=*******' \
--data-urlencode 'client_secret=*******' \
--data-urlencode 'grant_type=client_credentials'

Пример клиентской функции: токен отдаёт ваш бэкенд (секрет не уходит в браузер):

async function getAuthToken(user, project, prevToken) {
  const res = await fetch('/api/your-backend/emailmaker-token', { method: 'POST' });
  const data = await res.json();
  return data.access_token;
}

Создание сущности EmailMaker plugin

Простейший вариант — HTML письма и тема:

emailmaker
  .init({
    getAuthToken,
    element: '#test',
    content: {
      subject: 'Тема письма',
      html: `КОД_ПИСЬМА`,
    },
    config: {},
  })
  .then((instance) => {});

Вариант с шаблоном и внешним id письма:

emailmaker
  .init({
    getAuthToken,
    element: '#editor',
    project: 'ключ-проекта-в-вашей-системе',
    content: {
      templateId: 22304,
      email: {
        id: 'crm-email-id-123',
      },
      blocks: [],
    },
    config: {
      theme: 'light',
      // advancedConfigs: { editor: { … }, pro: { … } },
    },
  })
  .then((instance) => {});

КОД_ПИСЬМА можно взять из нашего образца или вставить HTML-код своего письма.

Объект редактора сразу: create()

init() возвращает редактор, только когда он готов и письмо из content уже показано. Обработчики при этом срабатывают раньше — внутри init(), — и сослаться в них на редактор нельзя: переменная ещё не присвоена. create() отдаёт объект редактора сразу, синхронно, а готовность — отдельным промисом:

const editor = emailmaker.create({
  getAuthToken,
  element: '#editor',
  content: { email },
  handleEmailInit: async () => {
    // Объект уже есть — к моменту события он присвоен.
    const compiled = await editor.compileEmail(undefined, { amp: true });
    await saveOnYourSide(compiled);
  },
});
await editor.ready;

Это обычный объект, как и результат init(): все методы — его собственные поля, их видят Object.keys, spread и Object.assign, любой метод можно подменить своим. Объект можно сразу положить в своё хранилище, подписаться на события или вызвать destroy().

Объект привязывается к редактору, как только тот собран, — ещё до показа письма из content: так вызовы из обработчиков (как compileEmail() выше) доходят до редактора. После привязки все вызовы идут прямо в редактор. До привязки объект ведёт себя так:

| что | до привязки | | --- | --- | | подписки handle* | запоминаются и цепляются до первого события — ничего не теряется | | асинхронные методы (show, compileEmail, getEmailSnapshot, …) | ждут готовности и выполняются | | setEmailMeta, setBlockMeta, notify | применяются при готовности, по порядку | | getElement() | узел из опций, если он передан элементом; для селектора — undefined | | getCodeErrors() | пустой список | | getConfig(), use() | бросают понятную ошибку — дождитесь ready или используйте useAsync() | | поля container, undoRedoService | undefined; чтение не бросает | | destroy() | отменяет инициализацию, ready отвергается с AbortError |

Между привязкой и ready письмо может быть ещё не показано. Если нужен именно показанный документ — например, снимок getEmailSnapshot(), — дождитесь ready.

Ошибка инициализации приходит отказом ready. Если объект создали, а ready не ждут, такая ошибка всплывёт в консоли как необработанная — это намеренно: иначе о том, что редактор не поднялся, не узнать. Исключение — destroy() до готовности: этот отказ ожидаемый и не шумит.

Повторный create() или init() в тот же узел описан ниже, в разделе «Повторный init() в тот же узел».

await emailmaker.create(options).ready — это ровно то, что делает init(options): переходить с одного на другое не обязательно.

React (обёртка)

В пакете есть готовый компонент: он сам создаёт контейнер, вызывает init при монтировании и destroy при размонтировании.

import Emailmaker from '@emailmaker/emailmaker/react';

const content = { email: { id: 'new' }, templateId: 1 };
const editorConfig = { theme: 'light' };
const editorStyle = { height: '100vh' };

export function EmailmakerEditor({ project, getAuthToken }) {
  return (
    <Emailmaker
      getAuthToken={getAuthToken}
      project={project}
      content={content}
      config={editorConfig}
      style={editorStyle}
    />
  );
}

Компонент принимает те же опции, что и init, плюс id, className, style и container (остальные атрибуты контейнера). element передавать не нужно — компонент подставляет свой div.

Два ограничения, о которых лучше знать заранее:

  • Любое обновление props приводит к reset редактора. Держите объекты и колбэки стабильными (useMemo / useCallback), иначе редактор будет пересоздаваться на каждый рендер родителя.
  • Ошибки инициализации компонент не пробрасывает и никак не показывает. Если init падает, вы увидите пустой контейнер — для диагностики вызовите init напрямую.

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

Минимальный каркас: монтирование, destroy при размонтировании.

import { useEffect, useRef } from 'react';
import * as emailmaker from '@emailmaker/emailmaker';

export function EmailmakerEditor({
  project,
  templateId,
  getAuthToken,
}: {
  project: string | number;
  templateId: number;
  getAuthToken: NonNullable<Parameters<typeof emailmaker.init>[0]['getAuthToken']>;
}) {
  const rootRef = useRef<HTMLDivElement>(null);

  useEffect(() => {
    let instance: Awaited<ReturnType<typeof emailmaker.init>> | undefined;

    (async () => {
      instance = await emailmaker.init({
        getAuthToken,
        element: rootRef.current ?? '#emailmaker-root',
        project,
        content: { email: { id: 'new' }, templateId },
        config: { theme: 'light' },
      });
    })();

    return () => {
      instance?.destroy();
    };
  }, [project, templateId, getAuthToken]);

  return <div id="emailmaker-root" ref={rootRef} style={{ height: '100vh' \}} />;
}

Скрытый старт и разворот

Редактор можно поднять заранее и показать позже — без второго запуска.

// Заранее: письмо загружено, его можно читать, собирать и сохранять. Интерфейса нет.
await emailmaker.init({ element: '#editor', hidden: true, content, getAuthToken });

// Когда понадобилось показать — тот же вызов без флага.
await emailmaker.init({ element: '#editor', content, getAuthToken });

Второй вызов не поднимает второй редактор: работающий экземпляр находится по контейнеру и разворачивается. Холст при этом не пересоздаётся, а состояние документа переживает переход.

Чем это отличается от показа новым init() в другой контейнер: там поднимается второй редактор со своим холстом, а всё, что накопил первый и что вы не передали заново в content (например метаданные письма), теряется вместе с ним.

Единственное требование к контейнеру: пока он скрыт, он должен оставаться в потоке рисования. display: none останавливает раскладку всего, что внутри, и письмо будет не с чего измерить — верстка уедет в мобильную. Нулевая высота, visibility: hidden или увод за экран подходят. Прятать сам холст — наша забота, не ваша.

Что заменяется, а что сохраняется при развороте:

| | переживает разворот | | --- | --- | | экземпляр и его службы | да | | холст (не мигает, не перезагружается) | да | | метаданные и состояние документа | да | | вёрстка письма | заменяется той, что передали в content |

Повторный init() в тот же узел

Как ведёт себя повторный init() или create() в тот же контейнер, задаёт опция ownership.

По умолчанию (ownership: 'single') — как в 1.1.89. У контейнера один объект редактора:

const first = await emailmaker.init({ element: '#editor', content });
const second = await emailmaker.init({ element: '#editor', content, config });
first === second; // true

second.destroy(); // уничтожает редактор — через любую ссылку
  • Повторный вызов применяет опции, как setConfig. Обработчики из опций подменяются сразу: события, которые придут дальше, уходят в обработчики нового вызова. Подписки, сделанные через объект (editor.handleSaveEmail(cb)), живут — объект ведь тот же.
  • Письмо показывается заново, только если оно отличается от последнего, которое вы задали сами — через init, show или reset. init(A) → show(B) → init(A) вернёт письмо A. init(A) → init(A) письмо не перерисует, и правки пользователя останутся.
  • Если вызов передаёт те же данные, что и прежний, — то же письмо, конфигурацию, пользователя и тот же набор обработчиков, пусть даже новыми функциями, как при каждой перерисовке компонента, — опции заново не применяются: handleSetOptions и handleOptionsChanged не приходят, токен не перезапрашивается.
  • Вызов, сделанный, пока прежний ещё стартует, вытесняет его: промис прежнего отклоняется AbortError (emailmaker.isSupersededInitError(error)), успешен только новый. Так ведёт себя и React StrictMode без отдельной уборки.
  • destroy() через любую ссылку уничтожает редактор, а handleDestroy, подписанный через объект, срабатывает.

ownership: 'counted' — свой объект на каждый вызов. Нужен, когда редактор в одном контейнере делят несколько частей приложения: страница подняла его, следующая вошла в тот же контейнер, а уборка прежней приходит позже — React размонтирует прежнюю страницу после того, как смонтировал новую, а в StrictMode вызывает эффект дважды.

const first = emailmaker.create({ element: '#editor', content, ownership: 'counted' });
const second = emailmaker.create({ element: '#editor', content, ownership: 'counted' });
await Promise.all([first.ready, second.ready]); // оба успешны, редактор один

first.destroy();  // снимает только долю first и его подписки
second.destroy(); // последняя доля: редактор уничтожается чуть позже
  • Каждый вызов получает свой объект со всеми методами общего редактора и держит долю во владении. Подписки объекта живут до его destroy().
  • destroy() снимает долю этого объекта. Редактор уничтожается, когда долей не осталось, — с короткой отложкой, чтобы уборка и новый вызов подряд (StrictMode) его не пересоздавали.
  • Действуют опции и обработчики последнего вызова. Уходит его доля — обработчики из опций переходят к последнему оставшемуся владельцу; письмо и настройки остаются как есть.
  • emailmaker.getInstance(element) отдаёт объект последнего вызова.

Смешивать режимы можно. Вызов без флага держит редактор, пока не вызовут destroy() его объекта, и получает общий объект контейнера. Доли counted живут поверх. destroy() объекта без флага уничтожает редактор со всеми долями — их объекты дальше ведут себя как после destroy(). В режиме разработки смешивание отмечается предупреждением в консоли.

Если повторный вызов не стартовал (упал токен или app_init, отменили через signal), отклоняется только он: редактор остаётся с прежними опциями и прежним письмом, восстановленным из снимка (текст и шапка; история отмен сбрасывается). Если вернуть не удалось, редактор уничтожается, а методы прежних объектов бросают EditorStartFailedError с причиной в cause — поднимите редактор новым init(). Отмена signal прежнего вызова после того, как пришёл новый, редактор не трогает.

init() в другой контейнер поднимает новый редактор.

Конфигурация

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

Повторный вызов init на тот же DOM-элемент отдаёт тот же объект и применяет новые опции — см. «Повторный init() в тот же узел».

element

Строка-селектор, Element или DocumentFragment: контейнер, куда монтируется редактор. Если элемент не задан, приложение может работать в фоновом режиме без видимого контейнера.

content

Секция content задаёт данные для редактора. Варианты:

{string}

HTML-разметка письма.

{object} параметры письма

{
	id?: string; // Уникальный ID письма в вашей системе.
	html?: string; // HTML письма.
	subject?: string; // Тема письма.
	preheader?: string; // Прехедер.
}

{object} шаблон, блоки, комментарии

{
	templateId?: string | number; // ID шаблона в EmailMaker.
	email?: object; // параметры письма (см. выше).
	blocks?: []; // блоки.
	comments?: []; // комментарии к письму.
}

Сменить контент после инициализации: instance.show(content).

Стили контента (commonStyles)

Не путать с config: объект commonStyles передаётся на верхнем уровне init / reset (тип ExportedApi.AppConfigMixin.Options).

  • Дефолт из сборки: именованный экспорт COMMON_STYLES — состав полей и их описания приходят с типами пакета, IDE показывает их подсказкой.

  • Частичное переопределение: можно передать только нужные ветки (например { block: { backgroundColor: '#000' } }) — приложение сливает их с COMMON_STYLES, чтобы панель «Стили контента», iframe и список общих блоков не ломались на «дырах» в объекте.

  • Приоритет: сохранённое email.common_styles важнее, чем init.commonStyles.

  • Сброс сохранённого в сторе плагина override: commonStyles: undefined в reset или updateConfig (с ключом).

  • Вкладка в UI: флаг config.commonStylesEnabled (часто true по умолчанию).

  • Структура: ветки по видам содержимого — block, text, headings, buttons, links и прочие; у каждой свои поля вроде цвета, шрифта и отступов. Точный состав виден в типе CommonStyles, он приезжает с пакетом.

  • Пресет зависит от сборки: у EmailMaker — системные шрифты и акцент #1C52DC, у UseBlocks — Google Fonts и свой акцент. Тот же объект служит базой, когда у письма нет сохранённых стилей.

  • Блоки, вставленные в письмо, наследуют эти стили: превью блока в песочнице рисуется теми же значениями, что и письмо.

config

Настройки UI редактора. После init используйте instance.setConfig, instance.updateConfig и instance.getConfig — не методы объекта emailmaker.

Список параметров секции config

| Параметр | Описание | Значение по умолчанию | | -------------------------------------- | --------------------------------------------------------------------------- | --------------------- | | theme | Тема плагина: light, dark. | light | | autosaveTimeout | Задержка перед автосохранением, мс. | 10000 | | mergeTags | JSON со списком динамических переменных. | undefined | | styles | Строка со стилями в формате CSS. | '' | | projectStyles | Свои шрифты, цвета бренда и соцсети проекта, см. ниже. | undefined | | | | | | headerShow | Показ шапки. | true | | headerArrowBackVisible | Показ стрелки "Назад". | true | | headerTitleVisible | Показ поля "Тема". | true | | headerPreheaderVisible | Показ поля "Прехедер". | true | | historyEnabled | Показ кнопки "История версий". | true | | codeEnabled | Показ кнопки "Code-mode". | true | | codeModeDirection | Режим показа редактора кода по умолчанию | none|left|right|bottom| | codeSideEnabled | Показ кнопки "Code-mode" в режиме, когда есть переключатель десктоп/мобайл. | true | | previewIconEnabled | Показ кнопки "Предпросмотр". | true | | previewModeEnabled | Ссылка на Предпросмотр. | true | | livePreviewEnabled | Показ кнопки "Тестировние в почтовиках". | true | | sendTestEnabled | Показ кнопки "Отправить тест". | true | | sharePreviewEnabled | Показ кнопки "Поделиться". | true | | webversionEnabled | Показ ссылки на веб-версию. | true | | commonStylesEnabled | Показ стилей контента. | true | | emailResponsiveControlEnabled | Показ переключателя адаптивности письма. | true | | templateNotEmAlertShow | Показ уведомления о том, что шаблон не из EM. | true | | | | | | emailDropdownMenuEnabled | Показ меню письма. | true | | emailDropdownMenuClone | Показ пункта "Клонировать". | true | | emailDropdownMenuImport | Показ пункта "Импортировать". | true | | emailDropdownMenuImportButton | Показ пункта "Импортировать" кнопкой | true | | emailDropdownMenuLock | Показ пункта "Заблокировать". | true | | emailDropdownMenuRemove | Показ пункта "Удалить". | true | | | | | | emailExportEnabled | Показ кнопки "Экспорт". | true | | exportHtmlEnabled | Экспорт в HTML. | true | | exportZipEnabled | Экспорт в ZIP. | true | | exportClipboardEnabled | Экспорт в буфер. | true | | exportWebHookEnabled | Экспорт в вебхук. | true | | exportOutlookEnabled | Экспорт в Outlook. | true | | exportPdfEnabled | Экспорт в PDF. | true | | exportPngEnabled | Экспорт в PNG. | true | | | | | | nextButtonEnabled | Показ второстепенной кнопки. | false | | nextButtonText | Текст на второстепенной кнопке. | '' | | saveButtonEnabled | Показ основной кнопки. | true | | saveButtonText | Текст основной кнопки. | '' | | commandButtonsEnabled | Показ основной и второстепенной кнопки. | true | | | | | | sidePanelFloating | Плавающая боковая панель. | true | | desktopMobileSwitchRule | Полоса переключения режимов. | true | | desktopMobileSwitchPanel | Панель переключения режимов. | false | | onlyCodeModeInMobile | вывод в мобиле только кода. | false | | | | | | pathEnabled | Показ хлебных крошек. | true | | copyPasteEnabled | Показ копирования-вставки блока в iframe. | true | | saveBlockEnabled | Показ кнопки сохранения блока. | true | | editImageControlEnabled | Показ кнопки редактирования изображения. | true | | | | | | menuDirection | Расположение боковой панели. | 'right' | | defaultBuildPanel | Настройка открывающейся вкладки по умолчанию. | ''/'empty'/'project'/'common'/'template' | | commentsEnabled | Показ кнопки "Комментарии". | true | | aiAssistentEnabled | Показ "AI ассистента". | true | | optimizeEnabled | Показ кнопки "Оптимизация". | true | | optimizeLinksEnabled | Показ проверки ссылок. | true | | optimizeImagesEnabled | Показ проверки картинок. | true | | optimizeSpamAssassinEnabled | Показ проверки SpamAssassin. | true | | optimizeCheckCodeEnabled | Показ проверки кода. | true | | settingsEnabled | Показ кнопки "Настройки". | true | | settingsTabEnabled | Показ таба "Настройки". Табы UTM-метки и Аннотации от него не зависят. | true | | UTMEnabled | Показ таба UTM-метки. | true | | annotationsEnabled | Показ таба Аннотации Gmail. Включён только в режиме pro. | false | | descriptionEnabled | Показ поля "Описание" в настройках. | true | | tagsEnabled | Показ поля Теги в настройках. | true | | switchDesktopMobilePropsEnabled | Показ переключателя мобильных свойств. | true | | stepToOtherElementEnabled | Показ кнопок перехода к другим элементам. | true | | deleteButtonEnabled | Показ кнопки удаления элемента. | true | | toggleSidePanel | Возможность схлопывать боковую панель. | true | | blocksSectionsShow | Показ меню блоков. | true | | blocksEmptyEnabled | Показ пустых блоков. | true | | blocksSavedEnabled | Показ сохранённых блоков. | true | | blocksCommonEnabled | Показ общих блоков. | true | | blocksTemplateEnabled | Показ блоков шаблона. | true | | blocksSearchEnabled | Показ поиска по блокам. | true | | blocksAddPanelEnabled | Показ панели добавления блока в визуальном редакторе. | true | | imagePathDropdownEnabled | Показ выпадашки с путём к изображению. | true | | | | | | formFieldImageTitleEnabled | Показ поля title в форме картинки. | true | | formFieldBorderEnabled | Показ полей изменения рамки. | true | | formFieldBorderRadiusEnabled | Показ полей изменения скругления. | true | | formFieldBoxShadowEnabled | Показ полей изменения тени. | true | | formFieldVisibilityEnabled | Показ кнопок изменения видимости элемента. | true | | formFieldExportAsPictureEnabled | Показ переключателя экспорт в картинку. | true | | | | | | formButtonFieldInsertImageEnabled | Показ кнопки вставки изображения в текст у кнопки. | true | | formButtonFieldVerticalAlignEnabled | Показ кнопок вертикального выравнивания у кнопки. | true | | formButtonFieldTextAlignEnabled | Показ кнопок выравнивания текста у кнопки. | true | | formButtonFieldBackgroundImageEnabled | Показ полей фонового изображения у кнопки. | true | | formButtonFieldPaddingsEnabled | Показ полей внутренних отступов у кнопки. | true | | formButtonFieldReplacerEnabled | Показ реплейсера у кнопки. | true | | | | | | formCellFieldVerticalAlignEnabled | Показ кнопок вертикального выравнивания у ячейки. | true | | formCellFieldBackgroundImageEnabled | Показ полей фонового изображения у ячейки. | true | | formCellFieldPaddingsEnabled | Показ полей внутренних отступов у ячейки. | true | | formCellFieldSizeEnabled | Показ полей ширины и высоты. | true | | | | | | formImageFieldVerticalAlignEnabled | Показ кнопок вертикального выравнивания у картинки. | true | | formImageFieldReplacerEnabled | Показ кнопок вертикального выравнивания у картинки. | true | | formImageFieldHeightEnabled | Показ поля высоты у картинки. | true | | | | | | formTableFieldBackgroundImageEnabled | Показ полей фонового изображения у таблицы. | true | | formDivFieldBackgroundImageEnabled | Показ полей фонового изображения у контейнера. | true | | formEmailFieldBackgroundImageEnabled | Показ полей фонового изображения у письма. | true | | | | | | formTextFieldTypografEnabled | Показ кнопки типографа. | true | | formTextFieldReplacerEnabled | Показ кнопки реплейсера. | true | | | | | | elementImageEnabled | Элемент Картинка. | true | | elementTextEnabled | Элемент Текст. | true | | elementHeaderEnabled | Элемент Заголовок. | true | | elementButtonEnabled | Элемент Кнопка. | true | | elementListULEnabled | Элемент Список UL. | true | | elementListOLEnabled | Элемент Список OL. | true | | elementDividerEnabled | Элемент Разделитель. | true | | elementSpacerEnabled | Элемент Отступ. | true | | elementSocialEnabled | Элемент Соцсети | true | | elementTableEnabled | Элемент Таблица. | true | | elementCountdownEnabled | Элемент Счётчик. | true | | elementVideoEnabled | Элемент Видео. | true | | elementAIimageEnabled | Элемент AI картинка. | true | | elementAItextEnabled | Элемент AI текст. | true | | elementCarouselEnabled | Элемент AMP карусель. | true | | elementAccordionEnabled | Элемент AMP аккордион. | true | | elementFormEnabled | Элемент AMP форма. | true | | | | | | imageCenterLocalUploadEnabled | Поле загрузки файла с компьютера в Image Center. | true | | deferEditorChrome | Строить кнопки шапки и правую панель сразу после первого кадра страницы: письмо появляется раньше, шапка и панель — мгновением позже. false — выключить, { header: false } или { panel: false } — выключить часть. | true | | imageCenterStockEnabled | Таб Стока фотографий. | true | | imageCenterGifEnabled | Таб Стока гифок. | true | | imageCenterEditorEnabled | Таб редактора изображений. | true | | compressMaxSize | Целевой вес картинки после клиентского сжатия, мегабайты (не байты). 0 выключает сжатие. По умолчанию 0.48. | см. типы | | compressMaxWidthOrHeight | Макс. ширина/высота после ресайза, px. 0 выключает сжатие. По умолчанию 2000. | см. типы |

Свои шрифты (projectStyles.fonts)

Шрифты передаёт ваше приложение в конфиге, списком config.projectStyles.fonts. Загрузить файл шрифта из интерфейса плагина нельзя. Переданные шрифты появляются в выборе шрифта группой «Custom fonts», применяются на холсте и попадают в HTML письма.

Одна запись — один файл или одно начертание. Записи с одинаковым family собираются в одно семейство с несколькими начертаниями.

const instance = await emailmaker.init({
	getAuthToken,
	element: '#editor',
	config: {
		projectStyles: {
			fonts: [
				// Семейство тремя файлами: в списке одна строка, три начертания.
				{ family: 'Brand', source_url: 'https://cdn.example.com/brand-400.woff2', category: 'serif' },
				{ family: 'Brand', source_url: 'https://cdn.example.com/brand-700.woff2', weight: '700' },
				{ family: 'Brand', source_url: 'https://cdn.example.com/brand-400i.woff2', style: 'italic' },
				// Google Fonts: начертания берутся из адреса.
				{ family: 'Inter', source_url: 'https://fonts.googleapis.com/css2?family=Inter:ital,wght@0,400;0,700;1,400' },
				// Своя таблица стилей: одна запись — одно начертание.
				{ family: 'Accent', source_url: 'https://cdn.example.com/accent/fonts.css' },
			],
		},
	},
});

| Поле | Обязательное | Описание | | ------------ | ------------ | -------- | | family | да | Имя семейства для CSS font-family. По нему же подписана строка в выборе шрифта. | | source_url | да | Адрес файла шрифта (.woff2, .woff, .ttf, .otf), таблицы стилей Google Fonts или своей таблицы стилей (.css). | | weight | нет | CSS font-weight файла. По умолчанию 400. У Google Fonts веса из адреса важнее этого поля. | | style | нет | normal, italic или oblique. По умолчанию normal. | | category | нет | sans-serif или serif. По умолчанию sans-serif. Тип семейства задаёт его первая запись. | | name | нет | Ваше название записи. В выборе шрифта не показывается. | | id | нет | Ваш идентификатор записи. Редактор его только хранит. |

Как шрифт попадает в письмо.

  • Файл шрифта подключается правилом @font-face, по одному на каждое начертание.
  • Таблица стилей, Google Fonts или своя, подключается тегом <link>.
  • Тексту редактор ставит инлайном безопасный шрифт: Helvetica, Arial, sans-serif, а для category: 'serif' — "Times New Roman", Times, serif. Сам шрифт задаёт класс em-font-*. Почтовый клиент без веб-шрифтов покажет безопасный шрифт.
  • Если шрифтом больше не размечен ни один элемент, его @font-face убирается из письма.

Требования к адресу.

  • Нужен https://. Адреса http:, data: и //host отклоняются.
  • Относительный путь (/fonts/brand.woff2) редактор достраивает до абсолютного от адреса вашей страницы. Так шрифт откроется и у получателя письма.
  • Если файл лежит на другом домене, сервер должен отдавать заголовок Access-Control-Allow-Origin. Без него браузер не применит шрифт, и на холсте будет запасной.
  • Файл должен открываться без авторизации: его скачивает почтовый клиент получателя.

Что ещё нужно знать.

  • Число шрифтов не ограничено.
  • Если две записи совпадают по family, weight и style, используется первая.
  • Запись с ошибкой пропускается, остальные применяются. Причина пишется в консоль с префиксом [emailmaker] projectStyles:.
  • В плагине шрифты доступны только для чтения: изменить их из интерфейса нельзя.
  • Не все почтовые клиенты показывают веб-шрифты. Gmail и Outlook для Windows покажут безопасный шрифт, поэтому проверяйте вёрстку и с ним.

Сменить список на лету: instance.updateConfig({ projectStyles }). Раздел передаётся целиком: он заменяет прежний, а не дополняет его.

В том же разделе передаются цвета бренда (colors, до 32) и соцсети проекта (socials, до 20). Полное описание полей — в типах ExportedApi.ProjectStyles.

Обработка событий

Обработчики передаются в init({ ... }) или подписываются на экземпляре: instance.handle*(listener, priority?). Подписка обычно возвращает функцию отписки. Обработчики могут быть async.

События handleSaveEmail, handleSaveBlock, handleSaveComment получают не сырой объект, а SaveEventPayload: { patch, value, prev?, source? } — полезно сравнивать patch и итоговое value.

handleSubjectChanged и handlePreheaderChanged оформлены иначе: через них подписываются на строковые значения темы и прехедера — см. emailmaker.d.ts.

Пример

emailmaker.init({
  element: '#test',
  content: { email: { id: '1' } },
  getAuthToken,
  handleReadEmail: async (id) => fetchEmail(id),
  handleSaveEmail: async (payload) => saveEmail(payload.value),
}).then((instance) => {
  const unsubscribe = instance.handleEmailChanged(async () => {
    /* ... */
  });
  /* unsubscribe(); */
});

События

| Обработчик | Описание | | ---------- | -------- | | handleReadEmail | Загрузка письма по id с вашего API (аргумент — строка id). | | handleSaveEmail | Сохранение письма; полезная нагрузка — SaveEventPayload с value и patch. | | handleRemoveEmail | Удаление письма. | | handleReadEmailRevisions | Список автосохранений / ревизий для письма. Автосохранение в нём отмечено autosave: true. | | handleReadEmailAutosave | Необязательно: последнее автосохранение письма (EmailRevision) или null, если его нет. Заведён — редактор восстанавливает несохранённую работу из него; нет — ищет в handleReadEmailRevisions свежайшую запись с autosave: true. Восстанавливается только снимок новее modified письма. | | handleEmailAutosave | Создано автосохранение (EmailRevision с autosave: true). Храните его как есть. | | handleRemoveEmailAutoSave | Удалено автосохранение. Сейчас редактор это событие не вызывает. | | handleReadBlocks | Список блоков проекта. | | handleReadCommonBlocks | Общие блоки. | | handleReadTemplateBlocks | Блоки шаблона в контексте письма. | | handleSaveBlock | Сохранение блока (SaveEventPayload). | | handleRemoveBlock | Удаление блока. | | handleReadComments | Комментарии к письму. | | handleSaveComment | Сохранение комментария. | | handleRemoveComment | Удаление комментария. | | handleSaveButtonClick | Клик по основной кнопке (например «Сохранить»). | | handleNextButtonClick | Клик по «Далее». | | handlePreviousButtonClick | Клик «Назад» в шапке. | | handleEmailInit | Письмо показано на холсте. Приходит при старте и на каждый show(), который меняет показанное: другое письмо; письмо без id (каждый такой показ — новый черновик); то же письмо, у которого отличается хотя бы одно из переданных полей — код, тема, прехедер, общие стили, — даже если холст при этом не перезаливается; show({ reload: true }). Не приходит, если show() с тем же id передаёт ровно то, что уже показано (непереданные поля не сравниваются), и на внутреннюю перезаливку холста. Если письмо правили в редакторе, повтор show() с прежним кодом снова нальёт его и пришлёт событие. Однократные действия («сохранить при первом открытии») на нём не стройте. | | handleEmailChanged | Изменился параметр письма. | | handleHtmlChanged | Изменился HTML-код. | | handleSubjectChanged | Изменилась тема (особая подпись — см. типы). | | handlePreheaderChanged | Изменился прехедер (особая подпись — см. типы). | | handleCloneEmail | Клонирование письма. | | handleShareEmail | Поделиться. | | handleLivePreviewEmail | Живой предпросмотр. | | handlePreviewEmail | Предпросмотр. | | handleValidate | Результат проверки кода (CodeError[]). | | handleTestEmailSend | Отправка тестового письма. | | handleTestEmailModal | Открыто окно тестовой отправки. | | handleDestroy | Перед уничтожением экземпляра. | | handleLoad | Завершена загрузка экземпляра; можно безопасно вызывать getEmail и др. | | handleLoadImage | Загрузка изображения пользователем; handleFileProxy, handleUrlProxy — прокси файлов/URL при необходимости. Вернуть URL; исключение из обработчика = отказ (редактор не грузит картинку на свой бэкенд), undefined — редактор дозагружает сам, кроме замкнутого контура (standaloneKey). | | handleNotify | Произвольное уведомление. Среди предупреждений (type: 'warning') — TEMPLATE_READ_ERROR (data: { templateId }): шаблон по templateId не прочитался, письмо открыто без него. Приходит один раз на шаблон за жизнь редактора, в handleError не попадает; заголовка у события нет и всплывающего сообщения редактор не показывает — покажите своё, если пользователю нужно знать. | | handleError | Ошибка (можно переопределить UI). | | handleSuccess | Успешная операция. | | handleReadLocale | Язык интерфейса (AppConfigMixin). Каталог возвращается текстом .po, JSON-строкой или готовым объектом LocaleData. | | handleTranslate | Пользовательский перевод строк. | | handleLimitUsage | Отображение квот / лимитов. |

Полный перечень и сигнатуры — в emailmaker.d.ts (ExportedApi.DataMixin.Events и смежные миксины).

Восстановление автосохранения

  • Восстановленное содержимое редактор считает текущим: событий правки (handleEmailChanged, handleHtmlChanged) не будет, пока пользователь не изменит письмо. Автосохранение при этом остаётся у вас, поэтому при следующем открытии письмо восстановится снова.
  • Удалять автосохранение после обычного сохранения редактор пока не просит: handleRemoveEmailAutoSave не вызывается.

Методы

Модуль экспортирует init (и именованные символы в ESM). Остальное — методы экземпляра после await emailmaker.init(...).

| Метод | Описание | | ----- | -------- | | init | Асинхронная инициализация: Promise<Instance>. | | show | Подмена контента (строка или объект Content). | | save | Сохранить текущее письмо по цепочке приложения. | | getEmailSnapshot | Поля открытого письма без сборки (Promise<Email>): те же значения, что у getEmail, минус compiled. | | getEmail | Текущее письмо вместе со сборкой HTML/AMP/текста. Нужны только поля — зовите getEmailSnapshot. | | compileEmail | Явная компиляция HTML/AMP/текста; опционально email и флаги форматов. | | setEmailMeta | Обновить meta текущего письма без полной замены. | | setBlockMeta | Обновить meta блока в кэше blocks DataSource по blockId. | | getBlocks | Блоки в текущем контексте (Block.meta round-trip при own-property). | | getComments | Комментарии. | | getEmailRevisions | Ревизии / автосохранения. | | getCodeErrors | Устарел. Ошибки линтера кода; отвечает только при открытом редакторе. | | validateCode | Проверить код открытого письма по требованию (Promise<CodeError[]>), без редактора. | | getConfig | Текущий config. | | setConfig | Полная замена настроек UI. | | updateConfig | Глубокое слияние с текущим config. | | notify | Показать уведомление (строка или объект). | | getElement | DOM-узел или фрагмент монтирования. | | destroy | Уничтожить экземпляр (вызывайте при размонтировании в SPA). | | reset | Переинициализация с новыми Options (Promise<Instance>). | | undoRedoService | Сервис отмены/повтора (undo, redo, снимки истории и др.). |

📂 Файловый менеджер

Для включения файлового менеджера необходимо в конфигурации инициализации указать параметры:

emailmaker.init({
  storageProvider: ..., // реализация интерфейса StorageProvider
  config: {
    imageCenterFileManagerView: true
  }
});

Секция fileManager управляет возможностями файлового менеджера. Все поля необязательные; незаданное поле берёт своё умолчание (у флагов enable* это true), отключает только явный false.

В секции можно задать и compressMaxSize с compressMaxWidthOrHeight — те же поля, что в корне конфига. Заданные здесь, они перекрывают корневые, но только внутри файлового менеджера: картинка, брошенная прямо на холст, загруженная через модалку или пришедшая с импортом HTML, по-прежнему сжимается по корневому значению.

Basic Operations

  • enableTrash — включает функциональность корзины для удаленных файлов. При включении файлы перемещаются в корзину вместо полного удаления. По умолчанию true
  • enableRenameFolder — разрешает переименование папок. По умолчанию true
  • enableRenameFile — разрешает переименование файлов. По умолчанию true
  • enableUpdateFile — разрешает обновление содержимого или метаданных файлов. По умолчанию true
  • enableEdit — разрешает редактирование файлов (изменение содержимого или свойств). По умолчанию true
  • enableMoveFile — разрешает перемещение файлов между папками. По умолчанию true
  • enableMoveFolder — разрешает перемещение папок. По умолчанию true
  • enableCopyFile — разрешает копирование файлов. По умолчанию true
  • enableCopyFolder — разрешает копирование папок. По умолчанию true
  • enableDelete — разрешает удаление файлов и папок. При включенной корзине файлы перемещаются в корзину. По умолчанию true
  • multiSelect — разрешает множественный выбор файлов и папок для групповых операций. По умолчанию true
  • defaultFolderName — Имя папки по умолчанию
  • availableImageExtensions — расширения в подсказке «Supported files» под областью загрузки пустой папки; выводятся с точкой (['jpg', 'png'] → .jpg, .png). Только подпись: что можно загрузить, поле не ограничивает. По умолчанию ['jpeg', 'svg', 'png']
  • dedupeUploadNamesOnClient — клиент сам подбирает свободное имя перед загрузкой: занятое photo.png уйдёт как photo_1.png, потом photo_2.png. Сюда же попадают копии из редактора изображений, загрузка по URL, копирование и перемещение; создать папку с занятым именем не даст — покажет ошибку. Стоит лишнего запроса списка папки перед каждой загрузкой, поэтому включать имеет смысл там, где коллизии имён не разруливает бэкенд. По умолчанию false
  • saveCopyToCurrentFolder — «Сохранить копию» в редакторе изображений кладёт файл в текущую папку. По умолчанию (false) копия уходит в папку по умолчанию, независимо от того, где открыт редактор
  • showNotifications — всплывающие уведомления файлового менеджера. По умолчанию true
  • sortOptions — белый список значений сортировки в дропдауне списка файлов ('date-desc' \| 'date-asc' \| 'size-desc' \| 'size-asc' \| 'name-asc' \| 'name-desc' \| 'type-asc'). Если не задан или массив пустой — доступны все варианты, которые отображает file-manager. Пример: ['date-desc', 'name-asc'] — скрыть сортировки по размеру и типу, если платформа их не реализует.

Pagination & Display

  • enablePagination — разрешает постраничную навигацию. Если отключено, все элементы загружаются сразу. По умолчанию true
  • unifiedCatalogFetch — работает только вместе с enablePagination: false. Запросы на список папок и список файлов сливаются в один запрос всего каталога, дальше нужный тип отбирается на клиенте: один вызов getItems вместо двух. При включённой серверной пагинации поле игнорируется. Ставьте false, если бэкенду важно получать раздельные запросы на папки и файлы. По умолчанию true
  • expandRootFolderOnInit — раскрывает корневой узел дерева папок при открытии; вложенные папки остаются свёрнутыми. По умолчанию true
  • previewFallbackToFileUrl — если у файла нет thumbnail и thumbnailUrl, для превью в таблице и сетке берётся file.url (только изображения). По умолчанию true

Client-Side Processing

  • clientSideSorting — клиентская сортировка файлов.

    • Если true, применяется стандартная сортировка (по имени по возрастанию).
    • Если указана функция, она принимает текущий массив файлов, необязательные sortBy и sortOrder, и возвращает отсортированный массив.
  • clientSidePaging — клиентская пагинация файлов.

    • Если true, применяется стандартная нарезка массива по page и limit.
    • Если указана функция, она принимает массив файлов, page и limit, и возвращает массив только для нужной страницы.
  • clientSideFilter — клиентская фильтрация файлов.

    • Если true, применяется стандартная фильтрация по тексту search.
    • Если указана функция, она принимает массив файлов и необязательный search, и возвращает отфильтрованный массив.

Cache Strategy

  • cacheStrategy — стратегия кэширования для оптимизации производительности.
    • ttl — время жизни кэша в миллисекундах. По умолчанию 1800000 (30 минут)
    • errorTtl — время жизни кэша для ошибок в миллисекундах. Если не задан, равен ttl
    • allowSortedInsert — разрешает вставку элемента в отсортированный массив без полной инвалидации кэша. По умолчанию true
    • allowSearchInsert — разрешает вставку элемента в массив с фильтрами без полной инвалидации кэша. По умолчанию true
    • invalidateOnPaginationFull — если страница полная, кэш помечается как устаревший при вставке нового элемента. По умолчанию true
    • comparator — функция сравнения двух файлов для сортировки. По умолчанию сравнение по имени
    • filterMatch — функция проверки, проходит ли файл текущий фильтр. По умолчанию поиск по имени

Интерфейс StorageProvider

Свойства

| Свойство | Тип | Описание | По умолчанию | | --------------------------- | --------- | ----------------------------------------------------------- | ------------ | | pathMode | boolean | Использовать путь как идентификатор для папок | - | | rootId | string | Пользовательский идентификатор корневой папки | '' | | trashPath | string | Путь к корзине/папке для удаленных файлов | - | | tempPath | string | Путь к временной папке для загрузок | - | | useSoftDelete | boolean | Включить программное мягкое удаление | false | | ensureFolderTrailingSlash | boolean | Добавлять к путям папок завершающий слэш | true | | validateDuplicates | boolean | Проверка на существование при операциях с файлами и папками | - |

Методы

Основные методы

| Метод | Параметры | Возвращает | Описание | | ------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | getItems | options:- folderId?: string- search?: string- sortBy?: string- sortOrder?: 'asc'\|'desc'- page?: number- limit?: number- itemType: 'all'\|'file'\|'folder' | { items: FileSystemItem[], pagination?: Partial<ApiPaginationResponse> } | Получить список файлов и папок с фильтрацией, сортировкой, пагинацией | | createFolder | name: string, parentid?: string | FileSystemItem | Создать новую папку | | uploadFile |