Command Palette

Search for a command to run...

Валидация параметров интеграции

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

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

Когда модуль проверяет параметры

Модуль проверяет параметры в два момента, и каждый раз в разном объёме:

  • При сохранении. Когда администратор магазина сохраняет секцию или ваш код отправляет значения параметров, модуль проверяет только отправленные параметры. Их правила он применяет к сохранённой конфигурации, поверх которой наложены отправленные значения, без значений по умолчанию из дескриптора. Поэтому правило может читать параметры из других секций. Если правило не проходит, сохранение отклоняется и ничего не записывается.
  • Полная валидация. Модуль проверяет всю собранную конфигурацию с подставленными значениями по умолчанию: все правила каждого параметра и общее правило дескриптора. От результата зависит, считается ли интеграция полностью настроенной. Полная валидация выполняется каждый раз, когда потребитель получает параметры и когда Admin показывает статус интеграции. Сохранение она никогда не блокирует.

Сохраняются настройки по секциям, поэтому конфигурация может быть корректной в каждой секции по отдельности и при этом неполной в целом. Такая интеграция получает статус Не завершено, и потребители не получат её параметры, пока администратор магазина не заполнит недостающее.

Схема показывает оба прохода рядом и то, где рядом с ними стоит проверка соединения:

При сохранении каждый отправленный параметр проходит встроенное правило, а затем собственный , и любая проблема отклоняет сохранение с ошибкой . Полная валидация разбирает всю конфигурацию целиком и решает, завершена ли интеграция, но сохранение она не блокирует. Проверка соединения не относится ни к одному из проходов. Администратор магазина запускает её отдельным действием, и она вызывает дескриптора только с параметрами, которые удалось получить, то есть для включённой и полностью настроенной интеграции. Как её написать, читайте в руководстве Как создать провайдер Модуля интеграций.


Встроенные правила

У каждого типа параметра () есть свои правила, например формат URL для или допустимые значения для . Поля конкретного типа добавляют новые, например и для или , и для . Все они перечислены в разделе Дополнительные поля по типу параметра.

отклоняет параметр без значения. Для всех типов, кроме и , значением не считается пустая строка, а для всех типов ещё и . Параметр с никогда не нарушает , потому что пропуск заполняет значение по умолчанию.

Форма в Admin тоже отмечает обязательные поля и не отправляет их пустыми. Исключение составляет секрет, у которого уже есть сохранённое значение: пустое поле оставляет его как есть.

Для параметра типа правило про пустую строку не действует, потому что пустая строка для него значение. На сервере одного достаточно, чтобы принять , и интеграция считается полностью настроенной с пустым полем. Форма в Admin не даст отправить пустое обязательное поле, а запрос к API Admin или виджет даст. Добавьте обязательному параметру значение , чтобы отклонять такие значения, как это делает провайдер ЮKassa для своих и .


Правила параметра

Если встроенных правил параметра недостаточно, добавьте ему функцию . Она получает значение параметра и контекст с двумя полями:

  • – конфигурация, по которой проверяется правило, с соседними параметрами из всех секций. При сохранении это сохранённые значения с наложенными поверх отправленными, без значений по умолчанию из дескриптора. При полной валидации это вся конфигурация после подстановки значений по умолчанию;
  • – сообщает о проблеме. Без проблема относится к самому параметру.

Например, код ставки НДС обязателен, только пока включены чеки:

providers/integration-my/services/my-integration.ts
1import { defineIntegration } from "@gorgo/medusa-integration"
2import type { OptionValidateContext } from "@gorgo/medusa-integration"
3
4const requiredWhenReceipt = (value: number | undefined, ctx: OptionValidateContext) => {
5 if (ctx.options.useReceipt && value == null) {
6 ctx.addIssue({ message: "Required when receipts are enabled" })
7 }
8}
9
10const descriptor = defineIntegration({
11 category: "payment",
12 displayName: "my.name",
13 options: {
14 apiKey: {
15 type: "string",
16 control: "secret",
17 secret: true,
18 required: true,
19 minLength: 1,
20 label: "my.apiKey"
21 },
22 useReceipt: {
23 type: "boolean",
24 default: false,
25 label: "my.useReceipt"
26 },
27 vatCode: {
28 type: "enum",
29 values: [1, 2, 3, 4, 5, 6],
30 label: "my.vatCode",
31 visibleWhen: { field: "useReceipt", equals: true },
32 validate: requiredWhenReceipt,
33 },
34 },
35 sections: [
36 {
37 id: "credentials",
38 title: "my.credentials",
39 options: ["apiKey"]
40 },
41 {
42 id: "receipts",
43 title: "my.receipts",
44 options: ["useReceipt", "vatCode"]
45 },
46 ],
47})

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

Условное поле проверяйте в и не сочетайте с . Поле, скрытое через , всё равно отправляется и проверяется, потому что форма в Admin подставляет и отправляет все поля своей секции. Скрытый параметр типа , , , или без уходит пустым, не проходит , и модуль отклоняет сохранение, пока поле скрыто.

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

Внимание: 

Правило, которое читает соседний параметр со , может видеть разные значения в двух проходах. Если этот параметр находится в секции, которая ещё не сохранена, при сохранении правило не найдёт его, а при полной валидации найдёт значение по умолчанию. Правило может пройти при сохранении, а интеграция останется в статусе Не завершено. Подставляйте значение по умолчанию соседнего параметра прямо в правиле, например для параметра с .


Правила для нескольких секций

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

providers/integration-my/services/my-integration.ts
1const descriptor = defineIntegration({
2 // ...
3 validate: (full, { addIssue }) => {
4 if (full.mode === "webhook" && !full.webhookSecret) {
5 addIssue({ path: ["webhookSecret"], message: "Required when mode is \"webhook\"" })
6 }
7 },
8})

Это правило выполняется только при полной валидации. Секция с сохранится в любом случае, а интеграция останется в статусе Не завершено, пока правило сообщает о проблеме. Если правило на самом деле касается одного параметра, задайте его в этого параметра, чтобы администратор магазина узнал о проблеме при сохранении.


Что видит администратор магазина

Сохранение, которое не прошло валидацию, возвращает ошибку , и Admin показывает её сообщение в уведомлении. В сообщении каждая проблема записана как , например .

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


Тестирование правил

экспортирует полную валидацию самого модуля, поэтому unit-тест может проверить дескриптор без запущенного приложения Medusa:

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

Например, тест для дескриптора выше:

providers/integration-my/__tests__/descriptor.unit.spec.ts
1import { collectValidationIssues } from "@gorgo/medusa-integration"
2import MyIntegrationProvider from "../services/my-integration"
3
4const descriptor = new MyIntegrationProvider().descriptor
5
6describe("my integration descriptor", () => {
7 it("requires a VAT code once receipts are on", () => {
8 expect(
9 collectValidationIssues(descriptor, { apiKey: "key", useReceipt: true })
10 ).toEqual([
11 { path: "vatCode", message: "Required when receipts are enabled" },
12 ])
13 })
14})

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

Материалы

Изменено 12 ноября 2026 г.·Редактировать страницу