npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@opsregistry/contracts

v0.15.0

Published

Operation specifications and shared schemas for opsregistry.

Readme

@opsregistry/contracts

Пакет со спецификациями операций для экосистемы opsregistry.

Здесь живут не реализации интеграций и не данные реестра, а общие схемы и типы, которые описывают универсальные операции. Эти спецификации могут использовать:

  • opsregistry/registry для описания операций;
  • runtime-адаптеры поставщиков;
  • приложения-потребители, которым нужна единая модель входа и выхода.

Что внутри

Сейчас пакет содержит первые спецификации из домена логистики:

  • logistics.shipment.quote
  • logistics.shipment.create
  • logistics.shipment.list
  • logistics.shipment.track
  • logistics.pickup.create

И первые спецификации из домена финансов:

  • finance.merchantPayment.create
  • finance.merchantPayment.createQr
  • finance.merchantPayment.getStatus
  • finance.merchantPayment.cancel
  • finance.fiscalReceipt.create
  • finance.fiscalReceipt.getStatus

И первые спецификации из домена S3-совместимого объектного хранилища:

  • storage.object.uploadFile
  • storage.object.deleteFile
  • storage.object.list
  • storage.website.put
  • storage.website.get
  • storage.website.delete

И спецификации физических запасов и склада:

  • inventory.stock.getAvailability
  • inventory.stock.receive
  • inventory.stock.issue
  • inventory.stock.reserve
  • inventory.stock.release
  • inventory.stock.transfer
  • inventory.stock.adjust

И первые спецификации электронного обмена документами:

  • documents.exchangeDocument.list
  • documents.exchangeDocument.get
  • documents.exchangeDocument.listChanges
  • documents.exchangeDocument.create
  • documents.exchangeDocument.send
  • documents.exchangeDocument.accept
  • documents.exchangeDocument.reject
  • documents.exchangeDocument.requestCancellation
  • documents.exchangeDocument.acceptCancellation
  • documents.exchangeDocument.rejectCancellation
  • documents.exchangeDocument.prepareSigning
  • documents.exchangeDocument.completeSigning
  • trust.signingEnvironment.inspect
  • trust.signingEnvironment.configure
  • trust.device.list
  • trust.certificate.list
  • trust.certificate.resolve
  • trust.digitalSignature.create

Каждая операция экспортирует:

  • operationCode
  • Zod-схемы входа и выхода
  • TypeScript-типы
  • минимальные метаданные режима доступа, если операция может выполняться публично или с авторизацией

Как этим пользоваться

import {
  shipmentQuoteInputSchema,
  type ShipmentQuoteInput,
  type ShipmentQuoteResult,
} from "@opsregistry/contracts/logistics/shipment-quote";

Пример резервирования запаса:

import { stockReserveInputSchema } from "@opsregistry/contracts/inventory/stock-reserve";

const request = stockReserveInputSchema.parse({
  demandReference: { type: "salesOrder", id: "SO-42" },
  lines: [
    {
      item: { sku: "PART-001" },
      quantity: { value: 2.5, unitCode: "KGM" },
    },
  ],
  idempotencyKey: "SO-42:reserve:1",
});

Принцип

У каждой операции своя собственная спецификация.

Пакет @opsregistry/contracts не означает “один общий контракт для всех операций”. Он означает единое место, где живут согласованные спецификации конкретных операций, чтобы разные адаптеры и приложения использовали один и тот же смысл операции.

Например, logistics.shipment.quote уже умеет выразить:

  • несколько грузовых мест с количеством, весом и габаритами;
  • доставку между терминалами и адресами;
  • забор груза, адресную доставку, упаковку, хрупкость и страхование;
  • отдельный выбор тарифов и дополнительных услуг провайдера;
  • внешние идентификаторы городов и терминалов конкретного провайдера;
  • каким режимом был выполнен расчет: public или authorized;
  • относится ли цена к публичному или персональному тарифу.

logistics.shipment.track описывает чтение состояния уже созданного отправления:

  • вход принимает shipmentId, trackingNumber, providerDocumentId, customerReference или externalIds;
  • выход возвращает нормализованный статус отправления;
  • история движения передается как массив событий с кодом провайдера, временем, локацией и исходным payload.

Граница электронного документооборота

documents.exchangeDocument.create создаёт у оператора черновик пакета с участниками и вложениями. Операция не подписывает и не отправляет документ. clientReference связывает пакет с объектом приложения, а idempotencyKey позволяет провайдеру или адаптеру защититься от повторного создания, если они поддерживают идемпотентность.

documents.exchangeDocument.send является отдельным юридически значимым действием. Вход всегда требует confirmLegalAction: true и явный signingMode: без подписи, подписью выбранной провайдером либо отложенной подписью. Закрытые ключи и PIN не входят в контракт. Внешняя подпись выполняется отдельной операцией trust.digitalSignature.create после подготовки подписываемых объектов.

documents.exchangeDocument.accept подтверждает деловое содержание входящего документа, а documents.exchangeDocument.reject отклоняет его с обязательным указанием причины. Это не транспортное подтверждение получения файла. Обе операции требуют confirmLegalAction: true, могут обработать весь пакет или выбранные attachmentIds и возвращают актуальное состояние документа. Если провайдер использует настраиваемый workflow, вызывающая система может передать action из массива availableActions, полученного через get.

availableActions нормализует только бизнес-смысл доступного перехода (accept, reject, send и т. д.). Идентификаторы этапа и действия остаются непрозрачными ссылками провайдера. Самостоятельное формирование криптографической подписи по-прежнему не смешивается с принятием документа и требует отдельного контракта.

Аннулирование отправленного документа является соглашением сторон, а не удалением записи. requestCancellation инициирует соглашение, acceptCancellation подтверждает полученный запрос, а rejectCancellation отклоняет его с обязательной причиной. Все три операции требуют явного confirmLegalAction: true. Удаление черновика, перемещение в корзину и необратимое уничтожение документа в эти операции не входят.

Локальная подпись разделена на три независимых шага. prepareSigning получает у оператора ЭДО хеши подготовленных вложений, trust.digitalSignature.create подписывает их в доверенной локальной среде, а completeSigning передаёт готовые подписи оператору и завершает выбранное действие. Закрытый ключ, PIN устройства и локальная сессия криптопровайдера никогда не входят в контракты.

Локальная доверенная среда

trust.signingEnvironment.inspect без изменения системы определяет, готово ли рабочее место к подписанию. Результат описывает компоненты через универсальные состояния: отсутствует middleware, устарел криптопровайдер, требуется лицензия, перезапуск или вмешательство поддержки. Названия конкретных продуктов остаются данными адаптера.

trust.signingEnvironment.configure устанавливает и настраивает только те компоненты, которые нужны найденному устройству и требованиям подписи. Операция требует confirmSystemChanges: true, но не принимает лицензионные ключи, пароли или PIN. Секреты получает локальная доверенная среда по собственным защищённым каналам.

trust.device.list отличает пассивные носители ключей от устройств со встроенной криптографией. trust.certificate.resolve автоматически подбирает сертификат по универсальным идентификаторам лица или организации, назначению ключа, сроку действия и требованиям к подписи. Например, российский ИНН передаётся как { scheme: "taxId", value: "...", jurisdiction: "RU" }, а не как отдельное поле контракта.

Каталог bridge содержит не бизнес-операции, а версионированный транспортный протокол локального исполнителя: manifest возможностей, сопряжение с HTTPS-origin приложения и конверт вызова операции. Grant всегда одноразовый или короткоживущий и выдаётся уже сопряжённым приложением. Это позволяет оставить пользовательский интерфейс в браузере, а криптографию и системную настройку выполнять в невидимом локальном сервисе.

bridgeOperationGrantClaimsSchema задаёт независимый от приложения формат допуска: компактный JWS с EdDSA, стандартными JWT claims и типом opsregistry-bridge-grant+jwt. Допуск связан с одним Bridge, origin, кодом операции, requestId и SHA-256 input, канонизированного по RFC 8785. Срок жизни и защита от повторного использования являются политикой локального Bridge.

Первичное сопряжение использует отдельные bridgePairingGrantHeaderSchema и bridgePairingGrantClaimsSchema. Самоподпись доказывает владение заявленным Ed25519-ключом, но доверие появляется только после подтверждения на локальной странице Bridge. Результат сопряжения различает ожидание подтверждения, успешное подключение, отказ и истечение срока.

Локальные возможности поставляются модулями. bridgeModuleManifestSchema описывает отдельный исполняемый артефакт для конкретной ОС, архитектуры и target triple: операции, разрешения, издателя, версию протокола, размер и SHA-256. Triple не ограничен перечислением и позволяет публиковать точные сборки для разных ABI Windows, Linux, macOS и других систем. Ed25519-подпись хранится отдельно и вычисляется над точными UTF-8 байтами файла manifest. Сам артефакт защищён подписанным хешем из manifest. Такой формат не зависит от языка реализации модуля и одинаково применим к онлайн-загрузке и офлайн-пакету.

bridgeModuleCatalogSchema описывает подписанный каталог релизов. Корневой ключ каталога делегирует ограниченные по времени ключи издателей, а каждая запись связывает операцию, точный target, manifest и бинарник. Монотонный sequence защищает от возврата к старому каталогу. Каталог хранит только HTTPS-адреса; приложение-потребитель передаёт Bridge код операции, но не URL исполняемого файла.

bridgeModuleInvocationSchema и bridgeModuleInvocationResultSchema задают небольшой JSON-протокол между core и отдельным процессом модуля. Он не зависит от Rust: модуль для конкретной ОС может быть реализован на любом языке, если принимает один вызов через stdin и возвращает один ответ через stdout с совпадающими версией протокола, invocation ID и кодом операции.

Публичный BridgeManifest разделяет установленные модули и доступность операций. Приложение видит, готова ли операция, может ли core установить её модуль или требуется устранить ошибку, но не передаёт Bridge URL исполняемого файла. Источник пакетов выбирает только доверенная конфигурация локального core.

Граница финансовых операций

finance.merchantPayment.create описывает входящую платежную попытку в пользу продавца/мерчанта: заказ в магазине, счет за услугу, QR СБП, карточный checkout и похожие acquiring-сценарии.

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

Если платежный провайдер умеет одновременно инициировать платеж и передавать данные для онлайн-кассы, используйте опциональное поле receipt в finance.merchantPayment.create. Для возврата или частичной отмены с фискализацией то же поле доступно в finance.merchantPayment.cancel.

Для всех операций используйте форму domain.resource.action, например finance.merchantPayment.create или finance.fiscalReceipt.create. Ресурс должен описывать бизнес-объект или bounded context, а не конкретного провайдера. Для вложенного ресурса допустимы дополнительные сегменты, например it.identity.token.refresh.

Примеры будущих отдельных финансовых поддоменов:

  • finance.payout.create для выплат клиентам или подрядчикам;
  • finance.bankTransfer.create для исходящих банковских переводов;
  • finance.invoice.create для выставления счета;
  • finance.billPayment.create для оплаты услуг внешнего поставщика.

Если меняется только метод оплаты внутри merchant checkout, например карта или СБП QR, это параметр finance.merchantPayment.*, а не отдельный провайдерский код операции.

Граница storage website операций

storage.object.* описывает работу с объектами внутри бакета: загрузить файл, удалить файл, получить список объектов. Опциональный websiteRedirectLocation в storage.object.uploadFile отражает object-level redirect header и зависит от поддержки конкретного S3-провайдера.

storage.website.* описывает конфигурацию static website hosting на уровне бакета: index/error documents, redirect-all requests и routing rules. Эти операции отделены от object-операций, потому что меняют настройки сайта целиком, а не отдельный файл.

Граница inventory

inventory описывает физический запас и его учётное состояние. Это не storage, который хранит файлы и S3-объекты, и не logistics, который оформляет и отслеживает перевозку.

  • товар идентифицируется через itemId, variantId, sku, gtin или externalIds, а не через ID конкретной таблицы;
  • количество всегда передаётся вместе с unitCode; дробные значения допустимы;
  • expirationDate хранит календарную дату годности партии в ISO-формате YYYY-MM-DD; это не timestamp и она не сдвигается между часовыми поясами;
  • мутации требуют idempotencyKey;
  • резерв меняет доступность, но не физический остаток;
  • transfer может ссылаться на shipment, оставаясь складской операцией;
  • adjust создаёт аудируемое исправление через дельту или фактический пересчёт и не удаляет историю.

Поля metadata и externalIds позволяют приложению сохранить локальный контекст, не добавляя его в универсальный код операции.

Граница documents и accounting

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

Например, входящий УПД можно получить через documents.exchangeDocument.get, а затем отдельно отразить в локальной системе операциями домена accounting. Один электронный пакет может породить несколько бухгалтерских записей, поэтому эти жизненные циклы не объединяются.

pageToken и cursor намеренно непрозрачны для потребителя. Адаптер может хранить внутри них номер страницы, идентификатор события, документа или редакции конкретного провайдера.

Display-only signing guidance

Optional provider-owned guidance in signing environment metadata is documented in docs/signing-guidance.md. It is compatible with the existing 0.12.0 metadata fields and requires no new operation, grant permission or package release.

Commerce и исходящие банковские поручения (0.14.0)

commerce/offer-common содержит неизменяемое предложение с точными десятичными количествами, целыми суммами minor units, реквизитами сторон, необязательными инструкциями оплаты, решением и общей ссылкой на заказ. Операции: commerce.offer.respond и commerce.order.list. Эти контракты не зависят от VARM. Транспортные подключения, PAT, локальные id баз данных и JWS-конверты приложений не являются частью универсальной коммерческой операции.

finance.bankTransfer.prepare, finance.bankTransfer.createDraft и finance.bankTransfer.getStatus описывают подготовку, создание банковского черновика и чтение состояния. Первый профиль — RU.domestic: обычный исходящий RUB-платёж организации/ИП, российские БИК/счета и явно заданные ИНН/КПП. Прочие страны и бюджетные/зарплатные сценарии требуют отдельных профилей.

clientPaymentId — идентичность в приложении; наличие этого поля не обещает идемпотентность конкретного банковского метода. Токены, сертификаты и ключи не передаются в operation input. Статус executed относится к банковскому документу; для учёта оплаты требуется подтверждение суммы/получателя (черновик мог быть изменён в банке). Подписание и фактическое исполнение не объединяются с createDraft.

Подтверждение исходящего банковского платежа (0.15.0)

finance.bankTransfer.verifyExecution принимает ожидаемый платёж, идентификатор банковского документа и дату создания. confirmed требует нормализованного доказательства исполненного списания с окончательными реквизитами. Остальные результаты: pending, mismatch, ambiguous, unavailable с машинной причиной. Исполнение документа само по себе не подтверждает соответствие ожидаемому платежу. Зачисление получателю и бухгалтерские проводки не входят в эту операцию.

Необязательный payment.executionReference — UUID, уникальный для платежа; он должен присутствовать в предварительно проверенном назначении как [UUID]. Приложение не переиспользует его для другого платежа. Провайдер выбирает доказательство: банковская операция либо другой поддерживаемый в будущем профиль. Обычный пользователь не загружает выписку вручную. commerce.order.list.paymentConfirmation при наличии показывает подтверждение списания плательщика, а не поступление продавцу.