Установка
Из каталога, по ссылке, из архива или руками; обновление, включение, удаление
Готовые расширения лежат в двух репозиториях: модули и темы. Панель видит их релизы и ставит одной кнопкой; архив из файла и папка руками тоже остаются.
Из каталога
Утилиты → Модули (или Темы), блок Каталог. В нём — последние релизы из подключённых источников с версией, описанием и состоянием: не установлено, установлено, есть обновление. Кнопка рядом делает то, что написано: Установить, Обновить или Переустановить — последняя перекачивает и ставит заново тот же релиз, если файлы на сервере повредились или зеркало обновило архив, не меняя версию. Дальше всё как при установке из архива: панель подскажет, что осталось включить, пересобрать или перезапустить.
Каталог обновляется раз в десять минут; кнопка Обновить над таблицей перечитывает источники сразу. Совместимость проверяется по unicoreApi релиза — несовместимое расширение показывается, но кнопка установки у него выключена.
Источники
Кнопка Источники открывает список того, откуда каталог берёт релизы. Встроенные источники — репозитории UnicoreCMS; их можно выключить, но не удалить. Свои добавляются двух видов:
| Тип | Что указать | Откуда берутся расширения |
|---|---|---|
| GitHub | Репозиторий в виде owner/repo | Релизы репозитория: каждый релиз — один архив <id>-<версия>.zip |
| Ссылка на каталог | Адрес JSON | Список расширений в файле, архивы по ссылкам из него |
Для закрытого репозитория GitHub у источника есть поле Токен — personal access token с правом чтения. Он хранится зашифрованным, наружу не отдаётся и уходит только на api.github.com; для открытых репозиториев токен тоже полезен: без него GitHub ограничивает число запросов.
Каталог по ссылке — это JSON такого вида, его удобно держать на зеркале или своём сервере:
{
"extensions": [
{
"id": "screens",
"kind": "module",
"version": "1.2.0",
"name": { "ru": "Скриншоты", "en": "Screenshots" },
"description": { "ru": "Галерея скриншотов игроков" },
"unicoreApi": "^1.4.0",
"download": "https://mirror.example.com/unicore/screens-1.2.0.zip"
}
]
}Поле download может быть относительным — тогда оно считается от адреса каталога. Как выкладывать релизы на GitHub, чтобы каталог их увидел, написано в публикации модуля.
По ссылке
Кнопка По ссылке там же принимает прямой адрес zip-архива: релиз на GitHub, зеркало, любой сервер. Для закрытого репозитория токен можно передать разово, в панели он не сохраняется. Ссылки на localhost и адреса внутренних сетей отклоняются — сервер не станет ходить внутрь своей сети по указке из панели. Архив проверяется и ставится так же, как загруженный из файла.
Из архива
Утилиты → Модули (или Темы) → Установить из архива. Панель принимает zip, внутри которого лежит module.json или theme.json — в корне архива либо в единственной папке.
Расширение распаковывается в modules/<id> или themes/<id>. Идентификатор берётся из манифеста, а не из имени архива. Если вы копируете папку руками, имя ей можно дать любое: ядро читает module.json и берёт идентификатор оттуда. Две папки с одним идентификатором — единственный случай, когда вторая не загрузится, о чём будет сказано в логе.
Уже установленное под тем же идентификатором заменяется. Прежняя папка сохраняется до конца установки и возвращается на место, если что-то пошло не так.
Новый модуль ставится выключенным — сам он ничего не сделает, пока вы не включите его на странице «Модули». Обновление уже установленного модуля состояние не меняет: был включён — останется включённым.
Панель показывает, что осталось сделать: включить модуль, пересобрать фронты, перезапустить сервер. Список зависит от того, что есть у расширения.
Руками
То же самое без панели:
# 1. Скопировать папку расширения
cp -r screens /path/to/unicore/modules/
# 2. Если у расширения есть client/ или admin/
pnpm run build:client
pnpm run build:admin
# 3. Перезапустить серверСерверная часть модуля грузится при старте, поэтому перезапуск нужен всегда — заодно на нём создадутся таблицы расширения, если они у него есть. Фронтовые части — это слои Nuxt, они попадают в приложение только при сборке.
pnpm install ставить расширение не нужно
Папки modules/ и themes/ не входят в воркспейс pnpm — это сделано намеренно. Иначе каждое поставленное расширение становилось бы проектом воркспейса, и pnpm install на боевом сервере падал бы с ERR_PNPM_OUTDATED_LOCKFILE: лок-файл репозитория не знает про расширения, которые владелец поставил у себя. Пакеты расширение берёт у ядра из корневого node_modules, а package.json внутри архива нужен только для сборки исходников.
Выключение
Выключенный на странице «Модули» модуль пропадает с сайта и из панели сразу, стоит перезагрузить страницу: список включённых модулей фронты получают вместе с публичным конфигом и убирают всё, что модуль добавил, — пункты меню, вставки в чужие экраны, свои страницы (они начинают отдавать 404). Пересобирать фронты для этого не нужно.
Перезапуск сервера после выключения всё же нужен: серверная часть модуля уже поднята, и его HTTP-маршруты продолжают отвечать до рестарта. А пересборка нужна в обратную сторону — когда модуль включают, а его слоёв не было в последней сборке фронтов.
Что проверяется до распаковки
| Проверка | Что отклоняется |
|---|---|
| Пути внутри архива | Файлы, выходящие за папку расширения (../) |
| Типы записей | Символические ссылки |
| Манифест | Битый JSON, отсутствие обязательных полей, чужой идентификатор |
| Версия контракта | Диапазон unicoreApi, несовместимый с ядром |
| Ссылки манифеста | Пути на файлы, которых в архиве нет |
| Размер | Слишком большой архив или слишком много файлов внутри |
Проверки не заменяют доверия к автору
Они защищают от испорченного и подделанного архива, но не от злого умысла: серверная часть модуля выполняется с правами процесса CMS. Ставьте только то, чему доверяете, — как плагин на игровой сервер.
Включение и выключение
Переключатель на странице «Модули». Выключенный модуль не загружается: его контроллеры, задачи и подписки на события не работают, таблицы и настройки остаются на месте. Чтобы изменение вступило в силу, сервер нужно перезапустить, а если у модуля есть фронтовая часть — пересобрать фронты.
Состояние хранится в modules/state.json, поэтому оно переживает перезапуск и обновление модуля. Тему включать не нужно: она начинает работать, когда вы выбираете её на странице «Темы».
Пересборка фронтов
Серверную часть модуля подхватывает перезапуск, а страницы и компоненты попадают на сайт только после сборки клиента и панели. Собирать руками не нужно: на странице «Модули» есть кнопка «Пересобрать» — она запускает сборку в фоне и показывает живой лог. Сайт всё это время работает на прежней сборке, новая подменяет её в конце.
Можно собрать что-то одно: тема и модуль без админской части требуют только клиента. Сборка тяжёлая по памяти — если она обрывается, поднимите лимит контейнера, сообщение об этом будет в логе.
Удаление
Удалять можно только выключённый модуль. Панель предупредит, что уйдёт вместе с ним:
- таблицы
mod_<id>_*; - настройки
mod_<id>_*иpublic_mod_<id>_*; - строки локализации
mod.<id>.*; - права
mod.<id>.*— в том числе выданные ролям и игрокам; - сама папка расширения.
Тема удаляется со страницы «Темы» вместе с папкой и своими строками theme.<id>.*. Активную тему удалить нельзя — сначала выберите другую и пересоберите фронт.
Удаление данных необратимо
Резервной копии CMS не делает. Если данные модуля могут понадобиться, снимите дамп базы до удаления.