Новый модуль для Medusa: плагины объявляют свои настройки, администраторы задают их прямо в Admin – без правок medusa-config и передеплоя.

В Gorgo мы весь последний год делаем плагины для Medusa, которые подключают магазины к сторонним сервисам: платёжным провайдерам, ERP, службам доставки. И в каждом всплывала одна и та же боль: настроить интеграцию. Ключи, режимы и вебхуки жили в и переменных окружения, поэтому любое изменение означало правку кода и передеплой, а каждый плагин ещё и строил свой экран настроек с нуля.
Сегодня представляем модуль интеграций для Medusa, который снимает обе рутины. Плагин объявляет свои настройки один раз, администраторы магазина задают их в сгенерированной форме прямо в Admin, без правок , без перевыкладок, и с шифрованием секретов.
Настройка плагина Medusa обычно сводится к двум рутинам, и обе болезненнее, чем должны быть.
Модуль интеграций выносит настройки плагина из кода в Admin и базу данных. Плагин описывает нужные ему настройки, администратор магазина заполняет форму в разделе Настройки → Интеграции, во время работы плагин читает готовый, проверенный и расшифрованный конфиг.
Как автор, вы только описываете форму. UI, хранение, шифрование и валидацию модуль берёт на себя. А если плагину нужно что-то, чего сгенерированная форма не выражает, можно подключить кастомный виджет.
Вы объявляете дескриптор через , где перечислены ваши опции и их типы, секции, в которые они группируются, и правила валидации. Из этого одного объявления Admin генерирует форму настроек: подходящий контрол для каждого поля, валидацию, условную видимость и маскированные секреты. Никакой UI писать не нужно.
Минимальный провайдер — это дескриптор плюс класс, который его поставляет:
1import { AbstractIntegrationProvider, defineIntegration } from "@gorgo/medusa-integration"2
3const descriptor = defineIntegration({4 category: "payment",5 displayName: "acme.name",6 supportsMultipleInstances: true,7 options: {8 apiKey: {9 type: "string",10 required: true,11 secret: true,12 label: "acme.fields.apiKey",13 },14 mode: {15 type: "enum",16 values: ["test", "live"],17 default: "test",18 label: "acme.fields.mode",19 },20 },21 sections: [22 {23 id: "credentials",24 title: "acme.sections.credentials",25 options: ["apiKey", "mode"]26 },27 ],28 testConnection: async ({ options }) => {29 const ok = await pingAcme(options.apiKey, options.mode)30 return ok ? { status: "passed" } : { status: "failed", message: "Invalid API key" }31 },32})33
34export class AcmeIntegrationProvider extends AbstractIntegrationProvider {35 static identifier = "acme"36 get descriptor() {37 return descriptor38 }39}Метки вроде — это i18n-ключи, которые берутся из переводов вашего плагина.
Зарегистрируйте провайдер в : модуль интеграций хранит и шифрует его настройки, а потребляющий модуль (здесь — платежи) читает их, сопоставляя по .
1module.exports = defineConfig({2 plugins: [3 {4 resolve: "@acme/medusa-payment-acme",5 options: {},6 },7 {8 resolve: "@gorgo/medusa-integration",9 options: {10 encryptionKey: process.env.INTEGRATION_ENCRYPTION_KEY,11 providers: [12 {13 resolve: "@acme/medusa-payment-acme/providers/integration-acme",14 id: "acme-1",15 },16 ],17 },18 },19 ],20 modules: [21 {22 resolve: "@medusajs/medusa/payment",23 options: {24 providers: [25 {26 resolve: "@acme/medusa-payment-acme/providers/payment-acme",27 id: "acme",28 options: { id: "acme-1" }, // совпадает с id провайдера интеграции выше29 },30 ],31 },32 },33 ],34})Во время работы плагин читает свою конфигурацию где угодно через и получает типизированный расшифрованный объект. Неполные или отключённые конфигурации не резолвятся, поэтому наполовину заполненный черновик не утечёт в продакшн.
1import { resolveIntegrationOptions } from "@gorgo/medusa-integration"2
3const { apiKey, mode } = await resolveIntegrationOptions({ identifier: "acme" })Один дескриптор даёт вашему плагину полноценную настройку:
Если вы уже поддерживаете плагин для Medusa, переход на модуль в основном механический: перенесите существующие опции в дескриптор и читайте их через там, где сейчас читаете переменные окружения. Все свои провайдеры мы перевели именно так (платежи, ERP и доставка), а полный пример можно посмотреть в примере all-integrations.
Пошаговое руководство проводит через весь процесс.
Ещё модуль приносит каталог Browse прямо в Admin. Администраторы магазина находят доступные интеграции и добавляют их, не трогая код. А поскольку UI настроек генерируется, ваш плагин выглядит аккуратно и нативно, в одном стиле с остальной панелью.
Установите модуль:
npm install @gorgo/medusa-integrationДальше зарегистрируйте провайдеры и объявите их настройки. Полное руководство по установке и использованию — в документации, а исходники — на GitHub.
Модуль интеграций сейчас в бете, и мы активно его развиваем: больше встроенных интеграций и растущий каталог. Если вы поддерживаете плагин для Medusa, мы с радостью поможем вам перейти. Если у вас магазин на Medusa, попробуйте и расскажите, чего не хватает. Присоединяйтесь к обсуждению в нашем Telegram-сообществе. Issues и Pull Request'ы всегда приветствуются на GitHub.