Расширения — это механизм добавления новых возможностей в Creatium Max с помощью кода. Каждое расширение работает в изолированной песочнице — расширения не имеют доступа к базе данных проекта, файлам других расширений и системным ресурсам сервера.

Создание расширения

Самый простой способ создать расширение - это загрузить шаблон попросить ИИ-агента (Claude Code, Codex, Cursor и тд.) сделать нужный вам функционал. В архиве шаблона есть все нужные инструкции и вся документация, которая может потребоваться агенту.
Но можно использовать и обычный ChatGPT, которому достаточно основу функции прислать, чтобы он сделал всю работу.
typescript
export default async function (req: Request): Promise<Response> { // Напиши функцию отправки письма на почту }

Структура файлов

  • my-extension/
    • CLAUDE.md и AGENTS.md - документация для ИИ агентов
    • deno.json - информация о расширении
    • migrate.ts - скрипт обновления расширения (если нужно)
    • api/
      • public/
        • …публично доступные ендпоинты
      • admin/
        • …ендпоинты, доступные только админам
    • actions/
      • …действия, доступные в редакторе сценариев
    • cron/
      • …скрипты, запускаемые по расписанию
    • static/
      • public/
        • …статические файлы, доступные публично
      • admin/
        • index.html - главная страницы расширения в админке
        • …статические файлы, доступные только админам
    • storage/
      • public/
        • …загруженные файлы, доступные публично
      • admin/
        • …загруженные файлы, доступные только админам
      • data.db - файл базы данных sqlite
      • …хранилище файлов (uploads, временные файлы и тд)

Идентификатор расширения

Можно использовать символы латинского алфавита, цифры и “-”.
Идентификаторы должны быть уникальными: в рамках одного проекта нельзя установить два расширения с одинаковым идентификатором.
Поэтому в качестве стандарта предлагается использовать формат “разработчик-название”. Например “viktor-cart”, где “viktor” это имя разработчика, студии или компании, а cart это название расширения.

/deno.json

Обязательный файл, в котором указывается идентификатор, версия и имя расширения. Идентификатор всегда соответствует названию папки расширения.
markdown
{ "name": "my-extension", "version": "0.0.1", "title": "Мое расширение" }

/api - HTTP ендпоинты

В папках /api/public и /api/admin лежат публично доступные ендпоинты. public досупны для любых запросов, admin только тем, кто авторизован в /cr-admin.
Каждый ендпоинт - это функция, которая на вход получает Request, а возвращает Response.
typescript
export default async function (req: Request): Promise<Response> { return Response.json({ message: "Hello, world!" }); }
Название файла напрямую отражается в URL. Файл /api/public/hello.ts доступен по адресу https://example.com/cr-ext/my-extension/api/public/hello.

/actions - действия для сценариев

В папке /actions находятся функции, которые автоматически подключаются в редактор сценариев, и которые могут быть вызваны из любого сценария. Формат такой же, как в /api, но работа только с JSON в обе стороны.
Чтобы в редакторе сценариев отображались именованные поля с описаниями, можно использовать JSON Schema в экспорте config.input.
typescript
export const config = { title: "Отправить письмо", input: { description: "Отправляет письмо на указанный адрес", type: "object", properties: { text: { description: "Полный текст письма", type: "string" }, subject: { description: "Тема письма", type: "string" }, email: { description: "Кому отправить?", type: "string" } }, required: [ "text", "subject", "email" ] } }
Если схема указана, она в том числе будет использоваться и для валидации входящих значений.

/cron - задачи по расписанию

В папке /cron находятся функции, которые переодически выполняются по указанному расписанию.
Запуск каждую минуту:
typescript
export const config = { schedule: "* * * * *" }
Каждый день в 8 утра:
typescript
export const config = { schedule: "0 8 * * *" }
И так далее. Это стандартный формат crontab.

/static - статические файлы

В папках /static/public и /static/admin лежат статические файлы, которые доступны всем и только админам, соответственно.
Если есть файл /static/admin/index.html, то он используется в качестве главной страницы расширения в админке.

/storage - постоянное хранилище файлов и баз данных

В этой папке скрипты расширения могут сохранять файлы любого формата. Это единственная папка, доступная для редактирования.
В ней же можно хранить базы данных SQLite (файлы .db или .sqlite), например /storage/data.db, и работать с ними, используя node:sqlite в Deno.

Админ интерфейс

Главная страницы расширения в админке - это /static/admin/index.html, которая показывается при открытии расширения.
Все, что внутри /static/admin и /api/admin доступно только после авторизации в админке проекта /cr-admin, то есть дополнительно слои безопасности добавлять не нужно.

Сессии и пользователи

Ендпоинты в /api получают на вход 2 HTTP-заголовка: X-Cre-Session-Id и X-Cre-Member-Id, которые невозможно подменить. В этих заголовках передаются идентификаторы сессии и пользователя из таблиц “Сессии” и “Пользователи” в базе данных проекта.
Используя эти заголовки можно делать функционал, привязанный к посетителям и пользователям.

Запросы к localhost

Чтобы делать запросы к своим ендпоинтам, или ендпоинтам других расширений, расширение может использовать localhost.
Например, запрос к http://localhost/cr-ext/my-extension/api/public/example будет работать независимо от того, на каком домене находится проект.

Ограничения

Чтобы одно расширение не могло нагрузить сервер и замедлить весь проект, на среду выполнения расширений установлены аппаратные ограничения: 0.5 CPU, 512MB RAM.
Эти ограничения обеспечивают стабильность: даже если расширение содержит бесконечный цикл или утечку памяти, проект продолжит работу.

Таймауты

По умолчанию все скрипты (api, actions) имеют таймаут в 30 секунд, а задачи по расписанию (cron) - 5 минут. Эти значения можно изменить в config.timeout.
typescript
export const config = { timeout: 120 // 2 минуты }

При поддержке Notaku