Справочник коннектора
Поля манифеста, подстановки, схемы ключа, форма кассеты, команды пакета, коды проверок и каталог глаголов — собраны из кода пакета проверки.
Справочник собран из кода пакета проверки: таблица полей здесь — та же, по которой проверка принимает ключи манифеста, а слова кодов — те же, что стоят за адресом под красной строкой. Пример целиком — Быстрый старт.
Поля манифеста
Поля верхнего уровня манифеста объявленной среды. Ключ вне этого списка проверка отвергает (unknown_key), нет обязательного — missing_key.
manifest_version· обязательное — версия формы манифеста — 1connector_id· обязательное — имя коннектора строчными словами через «_», до 64 знаков; сversion— адрес ревизииconnector_id@versionversion· обязательное — номер ревизии — целое от 1; правка содержимого — новый номерauthor· обязательное — автор — строка до 64 знаковfamily· обязательное — семейство — предмет, с которым работает коннектор (shipment,booking,bonus); от него зависит, где запись только глаголом платформыprovider· обязательное — провайдер — служба, к API которой ходит коннектор, строчными словами через «_»environment· обязательное — среда:declarative— описание операциями и шагами;code— модуль с инструментамиauth· обязательное — как ставится ключ:scheme(см. «Схемы ключа»),fields— поля кредов{ name, secret, label? },exchange— обмен ключа на токенrecipients· обязательное — хосты, к которым уходят запросы: точные имена или*.домен; первая запись — хост шагов без своегоhostoperations· обязательное — операции: чтения (read) и эффекты (effect) с шагами запросов, привязкой к глаголуbindsили блокомtoolcontract_tests· обязательное — кассеты — записанные ответы API:{ cassette: "cassettes/<имя>.json", taken_at: "ГГГГ-ММ-ДД" }description· необязательное — что коннектор делает — строка до 500 знаковsettings· необязательное — несекретные настройки подключения, которые форма кабинета спросит у компании:{ name, label, kind?, required? }probe· необязательное — имя чтения, которым проверяется ключ при подключении; без него проверкаprobe_declaredкраснаяinbound· необязательное — точки входа — адреса, на которые служба шлёт события подключения
Подстановки
Значение в фигурных скобках в пути, параметрах, заголовках и теле шага, в охране цены и в результате — подстановка: корень и путь через точку. Выражений нет; корень вне списка — bad_template. «?» в конце ({input.comment?}) — нет значения, ключ опускается; только целым значением.
input— вход операции:{input.<поле>}— поля, которые глагол собирает из аргументов моделиkey— токен бизнес-ключа этой операции:{key}— короткий, для номера заявки или ключа повтора у службыorder— токен ключа заказа:{order}— у чтений и отмены, чтобы найти созданноеstep— ответ прежнего шага:{step.<id>.status},{step.<id>.body.<путь>},{step.<id>.headers.<имя>}; сегмент пути в теле ответа чтения может выбрать элемент массива по полю —{step.<id>.body.items[type=image].url}approved— значения карточки, одобренные оператором:{approved.<поле>}— например, цена «не дороже одобренного»item— элемент массива внутри узлаeachрезультата:{item.<путь>}— только тамconnection— несекретная настройка подключения: ровно{connection.settings.<имя>}изsettings, только в шагахinbound— адрес точки входа этого подключения: ровно{inbound.<точка>.address}изinbound, только в шагах
Схемы ключа
auth.scheme — как дверь платформы кладёт ключ подключения в запрос. Значения ключа в манифесте нет: только поле кредов и его назначение.
bearer— ключ уходит заголовкомAuthorization: Bearer <ключ>header— ключ уходит заголовком, имя которого называетheader_namequery— ключ уходит параметром запроса, имя которого называетquery_namebasic— значение поля кредов в base64 уходит заголовкомAuthorization: Basic …
Обмен ключа на токен — auth.exchange (вид client_credentials): поля кредов — ровно client_id и client_secret, токен из ответа обмена дверь ставит в Authorization: Bearer каждого шага.
Кассета
Кассета — записанный контракт службы: вход операции, обмены «запрос → ответ» и ожидание. Ключ вне списка проверка отвергает. Сбои — обрыв ответа, повтор, задержку — пакет вносит сам, руками их в кассету не пишут.
name· обязательное — имя сценарияoperation· обязательное — операция манифеста, которую проигрывает кассетаtenant_id· обязательное — компания прогона — любой uuidconnection· обязательное — подключение прогона:{ id, state, endpoint? }secret· обязательное — ключ прогона — фикстурная строка от 8 знаков (у обмена ключа на токен — объект «поле кредов → значение»); настоящий ключ не кладитеinput· необязательное — вход операции; нуженinputилиargsargs· необязательное — аргументы глагола: вход, бизнес-ключ и ключ заказа из них выведет сам глаголnow· необязательное — момент прогона в ISO, если сценарию важно времяkey· необязательное — токен бизнес-ключа операцииorder_key· необязательное — токен ключа заказаapproved· необязательное — значения, одобренные оператором (цена)exchanges· обязательное — обмены «запрос → ответ»:{ method, path, query?, respond: { status, body?, headers? }, times? };times— сколько раз обмен выдаётся,"*"— без пределаexpect· обязательное — ожидание чистого прогона:{ outcome: confirmed | rejected | unknown, result?, reason? }description· необязательное — откуда пример: по документации службы или живой снимок
Команды пакета
node dala-connector-kit.mjs conformance <манифест.json> [--json]— проверить манифест; кассеты из contract_tests — пути от папки манифеста; красная строка — с адресом страницы кодаnode dala-connector-kit.mjs bundle <манифест.json>— напечатать тело публикации { manifest, cassettes, suite_version } (только при зелёном наборе)node dala-connector-kit.mjs conformance <манифест.json> --executor <файл.mjs>— среда code: прогнать кассеты вашим исполнителем (см. sandbox)node dala-connector-kit.mjs sandbox— напечатать песочницу шагов-кода (тот же исполнитель, что на сервере): сохраните как dala-code-sandbox.mjs,npm i quickjs-emscripten@0.32.0node dala-connector-kit.mjs catalog— каталог глаголов: схемы, потолок, правило «результат несёт ссылку»node dala-connector-kit.mjs sample <образец>— рабочий образец в форме тела публикацииnode dala-connector-kit.mjs init <имя> [папка]— шаблон пакета автора: агент, навык, знание, шаг-код с примером, кейс передачиnode dala-connector-kit.mjs check <папка> [--executor <файл.mjs>] [--json]— правила двери пакета без базы; примеры шага — вашим исполнителем (см. sandbox)node dala-connector-kit.mjs pack <папка> [-o <файл.zip>]— архив для «Загрузить пакет» в кабинете песочницы (≤ 2 МБ)node dala-connector-kit.mjs catalog --packages— глаголы каталога и чтения шага, которые может назвать пакетnode dala-connector-kit.mjs case <документ.json> [--json] [--words]— проверить документ дела (формат case@1): все ошибки разом; --words — дело простыми словамиnode dala-connector-kit.mjs case --format— справка по формату документа делаnode dala-connector-kit.mjs --help— эта справка
Коды проверок
Строка пакета на каждую проверку набора; красная печатает под собой адрес страницы кода.
- schema — Манифест не прошёл строгую грамматику: ключ вне формы, значение не той формы или ссылка в никуда. Остальные проверки пропущены — без годной схемы им нечего читать.
- environment — Среда манифеста вне тех, что проверяет пакет.
- recipients_declared — Список
recipientsназывает внутреннюю сеть, адрес-литерал, имя без домена, путь, учётку или порт — либо у шагов без своегоhostпервая запись не точное имя хоста. - auth_fields — Поля ключа
auth.fieldsне сходятся со входом. У объявленной среды без обмена ключа на токен — ровно одно поле, с обменом — ровноclient_idиclient_secret; назначение поля — одно из access · hook · refresh · token · merchant · webhook · portal. У шагов-кода каждое поле стоит меткой{{secret:<имя>}}в модуле, и каждая метка называет объявленное поле. - forbidden — В подстановках шагов — обращение к переменным окружения, файлу или выход из пути (
${,file:,data:,../,__proto__,eval), либо путь шага начинается с//. - effect_bound — Право записи. Эффект (
class: "effect") объявлен без привязки к глаголу и без блокаtool; запись-инструмент стоит в семействе, где у платформы свой процесс или писатель факта (домен каталога, семейство или провайдер коннектора ядра); или шаг с методом POST, PUT, PATCH или DELETE не объявлен ни эффектом, ни безопасным. - verb_declared — Адрес глагола в
bindsне объявлен в каталоге, глагол другого семейства, чемfamilyманифеста, чтение привязано к команде (или эффект — к чтению), либо один глагол исполняют две операции. - idempotency — У эффект-операции нет ключа повтора (
idempotency), ключ не стоит на первом эффект-шаге или у глагола нет бизнес-ключа. - reconcile_path — У эффект-шага нет сверки — потерянный ответ нечем установить; сверка ищет не по ключу; или сверка не возвращает поле, которое дальше читается из тела эффект-шага.
- compensation_declared — Компенсация
compensateне совпала с глаголом: у необратимого глагола объявлена компенсация, у компенсируемого её нет или она не той операцией. - budget_timeout — Бюджет операции меньше её работы: вызовов меньше, чем шагов и опросов, или время опроса больше
total_ms. У шагов-кода — общий срок меньше срока одного запроса или у входа обменом меньше двух запросов. - status_mapping_total — Таблица значений результата
{ from, map }выдаёт слово вне словаря глагола, не покрывает статусы службы изprovider_statusesили перечня статусов нет вовсе. - hold_preview — Глагол удерживается для одобрения оператором, а у операции нет предпросмотра — карточку одобрения построить нечем.
- contract_tests — Кассет нет или файла кассеты из
contract_testsнет рядом с манифестом — годность не доказать. - effect_guarded — Эффект значимого глагола достижим без охраны цены по одобренному значению
{approved.…}. - cancel_free_only — Отмена проводит эффект не только при бесплатной отмене: предпросмотр не отображает условия отмены службы
cancel_termsвfree, или платная ветка доходит до эффекта. - probe_declared — У манифеста нет пробы ключа
probe— ключ подключения нечем проверить, и подключение не станет рабочим. - reconcile_carries_ref — Результат глагола создания несёт ссылку заявки службы, а
provider_refвresultоперации не объявлен, читает не тело эффект-шага или сверка не возвращает поле, из которого он читается. - cassette_run — Кассета не проиграна как ждали: форма кассеты, операция или инструмент не найдены, вход не прошёл схему, запросы ушли вне обменов кассеты, исход разошёлся с
expect; или операция не покрыта кассетой (у эффекта — кассетой с исходомconfirmed). У шагов-кода ещё — не подан исполнитель. - recipients_observed — Прогон ушёл к хосту вне
recipients, или точный получатель объявлен, а ни одна кассета к нему не ходила. - result_shape — Подтверждённый результат не проходит схему глагола, контракт операции писателя или
output_schemaинструмента, либоprovider_refпуст. - retry_no_duplicate — Повтор тем же ключом отправил новый эффект-запрос — служба исполнила бы действие дважды.
- unknown_on_lost_response — Пакет терял ответ эффекта, и исход не установила сверка, запрос ушёл повторно или журнал остался в полёте.
- timeout — Пакет задерживал ответ дольше таймаута операции, и запоздавший ответ принят как подтверждённый без сверки или назван отказом.
- kind_matches_effect — Вид операции не совпал с поведением: чтение совершило эффект-запрос или писало журнал, эффект не совершил ни одного.
- token_exchange — Манифест объявил обмен ключа на токен
auth.exchange, а кассета его не проиграла, креды ушли не только в query обмена или шаг ушёл без токена вAuthorization: Bearer. - tools_classified — Инструменты манифеста не совпали с функциями модуля
module.exports.tools, или форма модуля не прочиталась. - reconcile_declared — Есть инструмент-эффект
egress, а в модуле нет функцииreconcile(keyToken, input, ctx)— потерянный ответ эффекта нечем установить. - module_shape — Модуль не годен:
module_hashне равен sha256 текста, модуль не загрузился, вmodule.exportsлишние ключи или в тексте запрещённые обращения (сеть мимо двери, таймеры,require,import,process,eval). - secret_never_visible — Значение ключа попало модулю, в результат или в журнал.
Коды схемы
Красная schema называет узел и код: $.operations[0].steps[1].method: bad_step.
- not_object — Манифест и каждый его узел — объект: массив, строка или пусто здесь не годятся. У шагов-кода: манифест и каждый его узел — объект.
- unknown_key — Ключ вне закрытой грамматики: молча проигнорированный, он снял бы ограничение. У шагов-кода: ключ вне закрытой грамматики ревизии
code@1: молча проигнорированный, он снял бы ограничение. - missing_key — Обязательный ключ не объявлен.
- bad_value — Значение не той формы.
- bad_environment — Среда вне перечня core · declarative · external · service · code. У шагов-кода: ревизия этой проверки — только среда «code».
- bad_auth — Схема ключа вне перечня bearer · header · query · basic, поле кредов без имени и назначения либо обмен ключа на токен объявлен неверно. У шагов-кода: поля ключей: имя, слово назначения из семи, подпись у спрашиваемых в форме; вход — получатель, путь, указатель и поле-приёмник.
- bad_recipient — Получатель — точное имя хоста или
*.домен(≥2 метки после*.), без схемы, пути, порта и*вне префикса. У шагов-кода: получатель — точное имя хоста или*.домен(≥2 метки после*.), без схемы, пути, порта и*вне префикса; список — от 1 до 8 записей. - bad_operation — Операция объявлена неверно: имя, класс, привязка или обязательства эффекта.
- duplicate_name — Имя повторено: операции и шаги различаются именем, второе такое же — какая из двух исполнится, неизвестно. У шагов-кода: имя или адрес повторены.
- bad_step — Шаг объявлен неверно: метод, путь, хост, тело или таблица статусов.
- bad_template — Подстановка вне закрытого набора: выражения, окружение и ссылки вперёд в декларации невозможны.
- bad_reference — Ссылка на операцию или шаг, которого нет.
- bad_binding — Привязка к глаголу — адрес
домен.существительное.глагол@ревизия; уeffectона обязательна. У шагов-кода: привязка к глаголу (IZ-S16):binds— адресid@revглагола каталога, один инструмент на адрес;preview— только у связанного эффекта и называет инструмент вида query этого манифеста. - bad_contract_tests — Контракт-тесты: у
core— файлы*.test.mjsмодуля, уdeclarative— кассеты с датой снятия. У шагов-кода: контракт-тесты: кассеты*.jsonс датой снятия — те, что доказывают годность модуля. - bad_settings — Настройки подключения: непустой список полей «имя · подпись · вид · обязательность», только у объявленной среды. У шагов-кода: настройки подключения: список полей «имя · подпись · вид · обязательность».
- bad_inbound — Точка входа: имя · схема подлинности (hmac_sha256_body · header_token · path_token) · назначение ключа входа · приёмник.
- bad_tool — Блок
toolобъявлен неверно: среда, адрес по форме реестра вне доменов каталога, описание либо сочетание с привязкой к глаголу. У шагов-кода: инструмент объявлен неверно: адрес по форме реестра вне доменов каталога, описание, вид query | egress, reconcile у egress, схемы. - schema_unreducible — Схема инструмента вне закрытой грамматики каталога: инструмент не допускается.
- context_argument — Инструмент просит контекст в аргументах (tenant, connection, secret…): его выбирает сервер, не модель (INV-031).
- bad_probe — Проба — адрес инструмента вида query, которому не нужны обязательные аргументы.
- bad_budget — Бюджет: число запросов, общий срок и срок одного запроса — в пределах платформы.
- bad_module — Модуль: имя файла, текст в пределах длины и sha256 текста.
Каталог глаголов
Глаголы платформы, к которым привязывается операция (binds); схемы, потолок и обратимость — node dala-connector-kit.mjs catalog.
shipment.parcel.quote@1· query — Варианты доставки посылки от адреса до адреса: цена в тенге, срок, класс услуги (курьер по требованию или посылочная сеть), как передать посылку и где получить. Цена и срок приходят от службы доставки — не называй клиенту цену или срок, которых нет в ответе. Название службы тебе не раскрывается: не выдумывай его.shipment.parcel.create@1· command — Создать отправление по выбранному варианту доставки: имя и телефон получателя. Цену и условия ты не задаёшь — их берёт сервер у службы доставки по ссылке варианта, и сотрудник одобряет карточку с этими цифрами. После вызова отправление считается созданным только когда результат confirmed; при unknown не обещай клиенту доставку и не создавай отправление повторно.shipment.parcel.status@1· query — Состояние отправления по ссылке: принято, в пути, ждёт в пункте выдачи, вручено, отменено или не доставлено, и чем подтверждено вручение, если служба это даёт. Не обещай срок, которого в ответе нет.shipment.parcel.cancel@1· command — Отменить отправление по ссылке, если служба доставки позволяет отменить бесплатно. Если отмена платная или недоступна — результат rejected с причиной, решение за сотрудником; клиенту не обещай возврат денег.media.image.generate@1· query — Картинка по текстовому описанию сервисом генерации компании. Контракт семейства для кода: модели не предлагается.media.image.generate@2· query — Картинка по текстовому описанию сервисом генерации компании — ссылкой или телом ответа. Контракт семейства для кода: модели не предлагается.booking.availability.search@1· query — Свободное время приёма по услуге: ближайшие варианты с врачом и часовым поясом клиники. Врача, календарь и точный момент резолвит сервер; код времени действителен только в этом ответе. Записать этот инструмент не умеет: запись — отдельной способностью записи на приём, если она предложена, иначе запись делает оператор.booking.appointment.create@1· command — Записать пациента на приём — ТОЛЬКО после его явного «да» на прочитанные время и врача. Сначала в этом же ответе найди время поиском свободного времени по ТОЙ ЖЕ услуге и возьми код нужного слота. До записи пациенту должно быть прочитано время и врач как в выдаче поиска, каждое время в форме «ДД.ММ ЧЧ:ММ, врач <имя>» (дата и время рядом), а его последнее сообщение — согласие.consent_quote— его слова согласия дословно из последнего сообщения (например «да»). Пациента, врача и точное время подставляет сервер. «Ну давайте», «наверное», встречный вопрос — не явное согласие: переспроси. Исход not_confirmed — прочитай пациентуread_backи спроси, записать ли.booking.appointment.cancel@1· command — Отменить запись пациента на приём по его просьбе — ТОЛЬКО после его явного «да» на прочитанные время и врача ЭТОЙ записи. Записи пациента сервер находит сам по номеру диалога: вызови без кода — у единственной записи исход not_confirmed вернётread_back(время и врач), у нескольких — choose_appointment со спискомappointmentsи их кодами: прочитай и спроси, какую отменить, затем передай её кодappointment_refв этом же ответе. Прочитай пациентуread_backдословно, в форме «<подпись времени>, врач <имя врача>», и спроси, отменить ли.confirm_quote— его слова согласия дословно из последнего сообщения (например «да»). «Ну, наверное», встречный вопрос — не явное согласие: переспроси. Чужие записи (другого человека или номера) не называй и не отменяй — на такую просьбу откажи и предложи связаться с клиникой. Переносом эта способность не занимается.