Руководство по OOMOL Connector SDK
@oomol-lab/connector — TypeScript-клиент для gateway OOMOL Connector. Используйте его, когда нужно быстро добавить интеграции с apps в backend продукта без самостоятельной поддержки connector infrastructure. Ваш код вызывает hosted gateway OOMOL через SDK; OAuth, обновление token и хранение credentials provider остаются на стороне gateway.
Package легкий и не имеет зависимостей; SDK собирает request и разбирает response. Для вызовов вроде gmail.search_threads, slack.post_message и notion.append_block не нужны codegen или CLI.
Основные темы:
- Как установить SDK, получить API key и выполнить первый вызов.
- Пять слов, описывающих всю модель: gateway, provider, action, connection, organization.
- Два пути вызова: dynamic string и namespace, а также чтение execution metadata.
- Как включить точные типы для отдельных actions без codegen.
- Как проксировать еще не смоделированные endpoints, просматривать catalog и выводить список connected apps.
- Как использовать
ProjectConnector, чтобы подключать аккаунты от имени ваших end users и выполнять actions для них. - Как использовать
OpenConnector, чтобы выполнять те же actions через open-source Connector runtime, который вы размещаете самостоятельно. - Как устроены ошибки, какие из них можно повторять, и как задавать scope, timeout и отмену вызовов.
Установка
npm install @oomol-lab/connector # или: bun add / pnpm add / yarn add
Требуется Node ≥ 18 из-за встроенных fetch и AbortController. SDK поставляется только с dist, не имеет runtime dependencies и помечен как sideEffects: false, поэтому корректно tree-shake’ится. Он работает в Node, Bun, Deno, edge runtimes и browser-based apps со стандартным fetch; в браузере API key должен передавать host.
Получение API key
Вам нужен personal API key OOMOL Connector вида api_…. Создайте его в OOMOL Console:
https://console.oomol.com/api-key
Задайте его как environment variable. В этом руководстве везде используется OOMOL_API_KEY. Gateway авторизует каждый request и получает ключ как Authorization: Bearer <apiKey>.
Personal key
api_…выполняет actions на ваших собственных connections. Чтобы подключать аккаунты для ваших end users, используйте отдельный project key (oo_proj_…) и clientProjectConnector; см. Подключите аккаунты для ваших пользователей. Чтобы разместить runtime самостоятельно вместо hosted gateway, open-source server использует собственный optional runtime token (oct_…) и clientOpenConnector; см. Самостоятельно размещенный runtime.
Быстрый старт
Создайте client, затем вызовите action. Две формы ниже эквивалентны.
import { Connector } from "@oomol-lab/connector";
const oomol = new Connector({ apiKey: process.env.OOMOL_API_KEY! });
// Путь 1: dynamic string. Можно вызвать любой action id.
const { threads } = await oomol.execute("gmail.search_threads", { query: "from:boss" });
// Путь 2: namespace sugar. Внутри тот же вызов.
const result = await oomol.gmail.search_threads({ query: "is:unread" });
execute напрямую возвращает output action. Если также нужны execution metadata, используйте executeRaw:
const raw = await oomol.executeRaw("gmail.search_threads", { query: "from:ceo" });
raw.data; // то же значение, которое возвращает execute()
raw.executionId; // execution id, назначенный server (полезно для support / корреляции logs)
raw.actionId; // отраженный action id
raw.message; // человекочитаемое message из success envelope
Основной call flow состоит из execute и executeRaw.
Понятия
В модели SDK есть пять ключевых понятий. Authentication, credentials и provider calls обрабатывает gateway:
| Термин | Что это |
|---|---|
| Gateway | Hosted service OOMOL Connector, с которым общается этот client. Он хранит credentials, выполняет реальные provider calls и возвращает единый envelope. SDK не выполняет integration logic локально. |
| Provider / service | Сторонний API (gmail, slack, github, notion, …). Это prefix <service> в action id. |
| Action | Операция у provider, идентифицируемая как "<service>.<action>" (например, gmail.search_threads). Actions предоставляет gateway, а client их вызывает. |
| Connection | Сохраненный и уже авторизованный credential для provider. Вы не работаете с token напрямую; вы указываете нужную connection через connectionName. OAuth и lifecycle credentials — задача gateway. |
| Organization | Optional tenant scope, отправляемый в header x-oo-organization-name. |
Та же лексика используется во всем SDK surface: action id всегда имеет вид "<service>.<action>", connectionName выбирает сохраненную connection, а в project client externalUserId идентифицирует одного из ваших end users.
Частые операции
| Нужно… | Используйте | Примечания |
|---|---|---|
| Выполнить смоделированную action | execute / executeRaw | Типизированный вызов в одну строку. executeRaw также возвращает { executionId, actionId, message }. |
| Обратиться к endpoint, который еще не смоделирован как action | proxy | Passthrough к upstream API; credentials connection подставляет gateway. |
| Передать actions в LLM / построить dynamic forms | catalog | Runtime JSON Schema (2020-12) для любой action или provider. |
| Узнать, что подключено | apps.list | Read-only список connections, которые вы уже связали. |
| Дать вашим users подключить их аккаунты | ProjectConnector | Отдельный project-scoped client для подключения аккаунтов от имени ваших end users и выполнения actions для них. |
Покрытие providers и actions предоставляет gateway. Сейчас поддерживается 600+ providers, и список растет; узнавайте доступное во время runtime через oomol.catalog.providers().
Точные типы (опционально)
Путь dynamic string компилируется для любого actionId. По умолчанию каждая action типизирована свободно (Record<string, any> на входе и выходе), чтобы новые actions можно было вызывать сразу. Для точных input/output types по отдельным actions и JSDoc установите companion types package и добавьте один side-effect import на каждый provider, который используете:
import { Connector } from "@oomol-lab/connector";
import "@oomol-lab/connector-types/gmail"; // точные types + JSDoc для gmail.*
import "@oomol-lab/connector-types/slack"; // …и slack.*
const oomol = new Connector({ apiKey: process.env.OOMOL_API_KEY! });
await oomol.gmail.search_threads({ query: "from:boss" }); // input + output теперь точные
await oomol.notion.append_block({ pageId, text }); // notion не импортирован → все еще свободный вызов
npm install -D @oomol-lab/connector-types
Без codegen, без generated files в commit, без CLI. Зарегистрированные actions получают literal completion и точные input/output types; незарегистрированные переходят к Record<string, any>. Если types package отстает от backend, новые actions все равно остаются вызываемыми через loose fallback. Core runtime не зависит от types package.
Нужно установить
moduleResolutionвbundler,node16илиnodenext, чтобы subpath imports (@oomol-lab/connector-types/gmail) разрешались. Подробности настройки см. в repository@oomol-lab/connector-types.
Конфигурация
Все fields, кроме apiKey, optional:
new Connector({
apiKey: process.env.OOMOL_API_KEY!, // required
baseUrl: "https://connector.oomol.com/v1", // default
organization: "acme", // default org → x-oo-organization-name
connectionName: "work", // default connection (лучше задавать per-call / через using())
timeoutMs: 30_000, // default per-request timeout
maxRetries: 2, // default; retry для 429 / 5xx / network с backoff + jitter
fetch: customFetch, // inject для tests / proxies / tracing
});
| Field | Default | Примечания |
|---|---|---|
apiKey | — | Обязателен. Отправляется как Authorization: Bearer <apiKey>. |
baseUrl | https://connector.oomol.com/v1 | Только ручное переопределение; автоматического переключения по env нет. |
organization | — | Tenant, в котором выполняется call. |
connectionName | — | Какую stored connection использовать, если у provider их несколько. Подходит как client default для простых setups; при нескольких connections задавайте per call или через using(). |
timeoutMs | 30_000 | Per-request timeout в миллисекундах. |
maxRetries | 2 | Retry для 429 / 5xx / network errors с exponential backoff и jitter. |
fetch | global fetch | Inject custom fetch для tests, proxy agents или tracing. |
Scopes и параметры вызова
Три слоя разрешаются в таком приоритете: per-call options > using() scope > client defaults.
using() возвращает immutable scoped sub-client, объединяющий указанные defaults; исходный client не меняется:
const work = oomol.using({ connectionName: "work", organization: "acme" });
await work.gmail.search_threads({ query: "label:urgent" }); // выполняется под "work" / "acme"
Per-call options действуют только на этот call и имеют наивысший приоритет:
await oomol.execute(
"gmail.search_threads",
{ query: "from:ceo" },
{
organization: "acme", // override org для этого call
connectionName: "alt", // выбрать другую connection для этого call
timeoutMs: 10_000, // более жесткий timeout для этого call
retries: 0, // отключить retries для этого call
signal: controller.signal, // передать AbortSignal
},
);
connectionName разрешается по тем же слоям. По wire он передается как header x-oo-connector-alias (field gateway называется alias); SDK surface использует connectionName.
Три клиента с первого взгляда
Package экспортирует три client: для personal connections, для end-user connections в project и для runtime, который вы размещаете самостоятельно. Они делят transport и error model; credentials, methods и types у них отдельные.
Connector | ProjectConnector | OpenConnector | |
|---|---|---|---|
| Auth | personal key api_… | project key oo_proj_… | optional runtime token oct_… |
| Общается с | hosted gateway OOMOL | hosted gateway OOMOL | open-source runtime, который запускаете вы |
| Действует на | ваши собственные connections | connections ваших end users | ваши собственные connections на вашем server |
| Идентифицирует user | — | externalUserId (вы выбираете) | — |
| Surface | execute, executeRaw, proxy, catalog, apps, namespaces | connect.*, waitForConnection, execute, executeRaw, forUser | execute, executeRaw, catalog, apps, health, namespaces |
| Для чего | вызывать providers, которые вы подключили | строить SaaS product, где каждый user связывает свои accounts | самостоятельно размещать весь runtime (localhost, Docker, ваша infra) |
Этот section начинается с personal Connector. ProjectConnector описан в Подключите аккаунты для ваших пользователей, а OpenConnector — в Самостоятельно размещенный runtime.
Proxy: вызов endpoint без action
Когда gateway еще не смоделировал endpoint как action, вызывайте его напрямую через proxy. Gateway все равно подставляет credentials connection; request и response сохраняют форму upstream API.
// Типизированный GET. ВАЖНО: field называется `endpoint`, НЕ `path`.
const repos = await oomol.proxy<Array<{ name: string }>>("github", {
endpoint: "/user/repos",
method: "GET",
query: { per_page: 5, sort: "updated" },
});
repos.status; // upstream HTTP status
repos.data.map((r) => r.name);
// POST с body и upstream headers (они идут provider, а не gateway).
await oomol.proxy("github", {
endpoint: "/repos/acme/widgets/issues",
method: "POST",
headers: { "X-GitHub-Api-Version": "2022-11-28" },
body: { title: "Tracking issue", labels: ["chore"] },
});
endpoint принимает path (разрешается относительно base URL provider) или полный URL, что полезно для providers с regional hosts, например https://eu.posthog.com/api/.... method — один из GET | POST | PUT | PATCH | DELETE. Response имеет вид { status, headers, data }. Proxy body строго проверяется на backend: неизвестные top-level keys отклоняются как invalid_input.
Catalog: просмотр providers и actions
Catalog предоставляет read-only runtime metadata для dynamic forms, validation и LLM tool definitions. Input/output schemas используют JSON Schema (2020-12) и не зависят от compile-time types package.
// Список providers; можно сузить server-side.
const all = await oomol.catalog.providers(); // все providers
const mailish = await oomol.catalog.providers({ q: "mail" }); // free-text search → ?q=
const some = await oomol.catalog.providers({ service: ["gmail", "slack"] }); // restrict → ?service=…
// Все actions одного service.
const actions = await oomol.catalog.actions("gmail");
// Полные metadata одной action, включая runtime JSON Schema.
const meta = await oomol.catalog.action("gmail.search_threads");
meta.name; // human-readable name
meta.requiredScopes;// OAuth scopes, нужные action
meta.inputSchema; // JSON Schema (2020-12) для input
meta.outputSchema; // JSON Schema (2020-12) для output
Каждый provider содержит { service, displayName, iconUrl, homepageUrl, categories, authTypes }.
Apps: список подключенных аккаунтов
apps.list() возвращает read-only view connections, которые gateway уже хранит для вас. Создание и удаление connections выполняется в Console.
const apps = await oomol.apps.list();
for (const app of apps) {
// { id, service, status, connectionName, … }; connectionName равен null, если не задан.
console.log(`${app.service}: id=${app.id} status=${app.status} connectionName=${app.connectionName}`);
}
// Чтобы выбрать конкретную connection, передайте ее connectionName как per-call selector.
const work = apps.find((a) => a.connectionName === "work");
if (work) {
await oomol.execute("gmail.search_threads", { query: "is:unread" }, { connectionName: "work" });
}
Обработка ошибок
Failures выбрасывают типизированную ConnectorError. Отмена со стороны caller (прерванный AbortSignal) отклоняется стандартной AbortError, поэтому ее можно обрабатывать отдельно от gateway или transport errors.
import { Connector, ConnectorError, isRetryable } from "@oomol-lab/connector";
try {
await oomol.slack.post_message({ channel: "#general", text: "shipped" });
} catch (err) {
if (err instanceof ConnectorError) {
err.code; // discriminable union, например "rate_limited", "credential_expired"
err.status; // HTTP status (0 для client-side / network errors)
err.requestId; // failure-correlation id
err.actionId; // если применимо
err.executionId; // если применимо
err.data; // upstream response body, например при provider_error
if (isRetryable(err)) {
// 429 / 5xx / network / rate_limited / proxy_upstream_timeout / request_in_progress
}
} else {
throw err; // не ConnectorError, например AbortError от caller cancellation; пробросить дальше
}
}
err.code — open union: известные backend codes получают autocompletion, а новые backend codes все равно проходят как strings. При обработке оставляйте default branch. Частые codes по группам:
| Группа | Codes |
|---|---|
| Input / request | invalid_input, invalid_request_payload, invalid_request_signature |
| App / provider | app_not_found, app_not_ready, app_auth_type_mismatch, provider_not_found, provider_not_configured, provider_config_not_found, provider_error |
| Credential / auth | credential_expired, scope_missing, user_oauth_client_required |
| Connection selection | connection_ambiguous, connection_account_conflict, connection_alias_conflict, connection_request_not_found, connected_account_not_found |
| Proxy | proxy_not_supported, proxy_upstream_error, proxy_upstream_timeout, proxy_response_too_large |
| Rate / concurrency | rate_limited, request_in_progress, request_key_conflict, request_key_used |
| Только client (status 0, request не отправлен или transport failure) | client_invalid_request, client_timeout, client_network_error, client_wait_timeout |
isRetryable(err) возвращает true для rate_limited, proxy_upstream_timeout, request_in_progress, HTTP 429, любого 5xx и transport failures (status 0). Он возвращает false для client validation errors (client_invalid_request) и лимита waitForConnection (client_wait_timeout); в этих случаях обычно нужно изменить call или waiting-flow.
Отмена и тайм-ауты
Передайте AbortSignal, чтобы отменить вызов; задайте timeoutMs, чтобы ограничить один call. Встроенный retry layer обрабатывает transient failures. Используйте retries: 0 для одной детерминированной попытки.
const controller = new AbortController();
setTimeout(() => controller.abort(), 50);
try {
await oomol.execute("gmail.search_threads", { query: "huge" }, { signal: controller.signal });
} catch (err) {
(err as Error).name; // "AbortError"
}
Подключите аккаунты для ваших пользователей
Connector выполняет actions на ваших собственных connections. ProjectConnector предназначен для SaaS products: ваши end users подключают свои аккаунты Gmail / Slack / GitHub / … через ваше app, а ваш backend выполняет actions от их имени. Это managed-auth model, используемая в продуктах вроде Composio и Pipedream Connect.
В managed auth credentials никогда не проходят через ваше application или какую-либо model. User авторизуется на gateway-hosted page; gateway хранит credential и автоматически обновляет token. Ваш код хранит только opaque identifiers.
Идентификатор конечного пользователя
externalUserId — ключ изоляции user для project client. Вы выбираете его сами, обычно из собственной user database. Project operations, такие как подключение account, ожидание connection и выполнение action, scoped к нему. Передавайте один и тот же externalUserId последовательно, и gateway будет изолировать connections каждого user.
Создание проектного клиента
ProjectConnector — отдельный client, создаваемый с project API key (oo_proj_…). Он открывает только project-scoped operations и не включает surface personal client: execute / namespace / proxy / catalog / apps.
import { ProjectConnector } from "@oomol-lab/connector";
const project = new ProjectConnector({ apiKey: process.env.OOMOL_PROJECT_API_KEY! }); // oo_proj_...
Сначала настройка в Console. Перед тем как backend будет подключать accounts, administrator создает project, provider config и project API key в OOMOL Console. Однократная настройка и соответствующий backend REST flow описаны в руководстве по OOMOL Connector SaaS. Этот SDK — типизированная обертка над тем же runtime API.
OAuth: создайте ссылку, затем дождитесь завершения
OAuth состоит из двух шагов: создать pending connection request, отправить user на authorization, затем дождаться завершения.
// 1. Создайте pending connection request для одного из ваших users.
const request = await project.connect.oauth("user_42", {
service: "gmail",
connectionName: "work", // назначаемое имя; позже используйте его для выбора account
returnUri: "https://app.example.com/connected", // куда gateway вернет user после callback
});
// 2. Отправьте user на страницу authorization provider.
redirectUserTo(request.authorizationUrl);
// 3. Poll, пока user не завершит процесс (или он не завершится ошибкой / не истечет). Возвращает final connection request.
const connected = await project.waitForConnection(request);
connected.status; // "connected" | "failed" | "expired"
connected.connectedAccountId; // id сохраненного account после подключения
authorizationUrl сначала открывает Connector-hosted entry page, где указаны ваш project и provider, который user собирается авторизовать, затем отправляет user на OAuth page provider.

waitForConnection poll’ит до тех пор, пока request не выйдет из состояния initiated, и возвращает его. Если user не завершит authorization, request естественно станет expired. Если раньше истечет maxWaitMs (по умолчанию 600_000 ms, соответствует expiry request), будет выброшена ConnectorError с code client_wait_timeout; прерванный signal отклонится стандартной AbortError.
Когда ваш returnUri вызывается, gateway добавляет query parameters, которые можно прочитать на callback page:
status=success
service=gmail
providerConfigId=pc-1
externalUserId=user_42
connectedAccountId=ca-1
…или при cancellation / provider error:
status=error
code=<connector-error-code>
message=<human-readable-message>
API key / custom credential: синхронно
Подключения через API key и custom credential сразу возвращают account. Только OAuth требует waitForConnection.
// Собственный upstream key end user (например, OpenAI sk-…), а не ваш oo_proj_ key.
const account = await project.connect.apiKey("user_42", { service: "openai", apiKey: "sk-..." });
account.available; // может ли account выполнять actions прямо сейчас
// Provider-specific credential fields, которые gateway валидирует по provider config.
await project.connect.customCredential("user_42", {
service: "jira",
values: { email: "user@acme.com", token: "..." },
});
Каждый вызов connect.* идентифицирует provider ровно одним из service или providerConfigId. Используйте providerConfigId, если в project несколько configs для одного service; service — простой случай.
Выполнение от имени пользователя
// Provider service выводится из prefix actionId ("gmail").
// Без connectionName / connectedAccountId используется latest active account этого user.
const out = await project.execute(
"user_42",
"gmail.search_threads",
{ query: "is:unread" },
{ connectionName: "work" },
);
Приоритет выбора account: connectedAccountId (конкретный account) выше connectionName (account по имени); если нет ни того ни другого, gateway использует latest active account этого user для данного provider. project.executeRaw возвращает такой же envelope { data, executionId, actionId, message }, как personal client.
Ограничение одним пользователем
forUser один раз привязывает externalUserId, чтобы в последующих calls не повторять id:
const user = project.forUser("user_42");
await user.connect.oauth({ service: "slack" });
const slack = await user.waitForConnection(/* request выше */ "req-id");
await user.execute("slack.post_message", { channel: "#general", text: "shipped" });
project.execute использует тот же registry @oomol-lab/connector-types, что и personal path: импортированные providers получают точный input/output, остальные остаются вызываемыми свободно.
Жизненный цикл connection
| Object | Когда вы его получаете | Key fields |
|---|---|---|
ConnectionRequest | возвращается connect.oauth, перечитывается через getConnectionRequest / waitForConnection | id, status (initiated → connected / failed / expired), authorizationUrl, connectedAccountId, externalUserId, connectionName, expiresAt |
ConnectedAccount | возвращается синхронно connect.apiKey / connect.customCredential; на него указывает завершенный OAuth request | id / connectedAccountId, status (active, reauth_required, error, disconnected), available, externalUserId, connectionName, service |
available равен true только когда все нужное для execution готово: provider config active, account active, underlying app active, credential существует. Оба status fields — open unions; оставляйте default branch, чтобы обработать новые backend statuses.
Переходите с Composio / Pipedream?
| Composio / Pipedream | @oomol-lab/connector |
|---|---|
userId / external_user_id | externalUserId |
connectedAccounts.initiate / createConnectToken (OAuth) | project.connect.oauth |
connectedAccounts.initiate + AuthScheme.APIKey | project.connect.apiKey |
waitForConnection() | project.waitForConnection() |
tools.execute(slug, { userId, arguments }) | project.execute(externalUserId, actionId, input) |
composio.getEntity(userId) | project.forUser(externalUserId) |
Самостоятельно размещенный runtime
Запускаете open-source Connector server самостоятельно — на localhost, в Docker или в собственной infra? OpenConnector — personal client для него. Он повторяет surface Connector (оба call paths, catalog, apps), но направлен на server, который запускаете вы, поэтому уже написанный code почти не меняется. Поднятие server — отдельная тема; см. руководство по самостоятельному размещению OpenConnector.
Open-source runtime — self-hostable counterpart personal продукта: один server, один user, actions выполняются на собственных connections этого user. Здесь нет organization и нет модели end users — server ваш.
import { OpenConnector } from "@oomol-lab/connector";
const open = new OpenConnector(); // default http://localhost:3000; fresh instance не требует auth
await open.execute("hackernews.get_top_stories", {}); // path 1 — dynamic string
await open.gmail.search_threads({ query: "from:boss" }); // path 2 — namespace sugar, те же registry types
await open.catalog.search("send email", { limit: 5 }); // catalog extras: search, services
await open.apps.list(); // read-only view connections runtime
Оба call paths и workflow precise types идентичны personal Connector; применяются те же side-effect imports @oomol-lab/connector-types.
Укажите ваш сервер
baseUrl — это origin server, а не URL /v1: client сам добавляет path prefix. Auth — один optional runtime token (oct_…), созданный в web console runtime (tab Access). Fresh instance без tokens отвечает без token; как только tokens появляются, server начинает их требовать.
const open = new OpenConnector({
baseUrl: "https://connect.internal.example.com", // server ORIGIN — не /v1 url
runtimeToken: process.env.OOMOL_CONNECT_RUNTIME_TOKEN, // oct_…; опустите, пока у instance нет tokens
connectionName: "work", // optional client-level default connection
});
Каждый field optional. timeoutMs, maxRetries и fetch ведут себя точно так же, как в hosted client.
Интерфейс только для runtime
OpenConnector добавляет несколько members, которых нет у hosted client, и убирает неприменимые:
await open.health(); // { ok, runtime } — проверка connectivity / auth
await open.catalog.services(); // все service id, у которых есть actions
await open.catalog.search("top stories", { limit: 3 }); // ранжирует actions по free-text relevance
await open.apps.listByService("github"); // connections одного service
await open.apps.authenticated(["github", "notion"]); // где сохранен REAL credential
Здесь нет proxy и нет using(). У выбора connection только два слоя: per-call connectionName переопределяет client-level default, а без обоих runtime возвращается к своей connection "default".
Управление находится в web console, а не в SDK. Создание connections, настройка OAuth clients и выпуск runtime tokens — server administration, намеренно вынесенное за пределы SDK.
OpenConnectorтолько использует то, что настроено в console; эта часть описана в руководстве по самостоятельному размещению. Как и в hosted client, service id, совпадающий с member name (execute/executeRaw/health/catalog/apps), продолжает работать черезexecute("<service>.<action>", …); скрывается только его namespace sugar.
Полный runnable tour — examples/open.ts.
Справочник
Connector (личный ключ api_…)
new Connector(config: ClientConfig)
oomol.execute(actionId, input, options?) // → output action
oomol.executeRaw(actionId, input, options?) // → { data, executionId, actionId, message }
oomol.<service>.<action>(input, options?) // namespace sugar для execute
oomol.using(scope) // → immutable scoped sub-client
oomol.proxy(service, { endpoint, method, query?, headers?, body? }, options?) // → { status, headers, data }
oomol.catalog.action(actionId, options?) // → ActionMetadata
oomol.catalog.actions(service, options?) // → ActionMetadata[]
oomol.catalog.providers(query?, options?) // → ProviderMetadata[] query: { service?: string[]; q?: string }
oomol.apps.list(options?) // → ConnectedApp[]
ProjectConnector (проектный ключ oo_proj_…)
new ProjectConnector(config: ProjectConnectorConfig)
project.connect.oauth(externalUserId, input, options?) // → ConnectionRequest (pending)
project.connect.apiKey(externalUserId, input, options?) // → ConnectedAccount (synchronous)
project.connect.customCredential(externalUserId, input, options?) // → ConnectedAccount (synchronous)
project.getConnectionRequest(connectionRequestId, options?) // → ConnectionRequest
project.waitForConnection(requestOrId, options?) // → ConnectionRequest options: { pollIntervalMs?, maxWaitMs?, signal?, timeoutMs? }
project.execute(externalUserId, actionId, input, options?) // → output action
project.executeRaw(externalUserId, actionId, input, options?) // → { data, executionId, actionId, message }
project.forUser(externalUserId) // → ProjectUser (те же methods, id привязан)
Input connect.* — { service | providerConfigId } & { connectionName?, … } (ровно один из service / providerConfigId). Options execute добавляют { providerConfigId?, service?, connectedAccountId?, connectionName? }.
OpenConnector (самостоятельно размещенный runtime, опциональный token oct_…)
new OpenConnector(config?: OpenConnectorConfig) // каждый field optional; baseUrl default — http://localhost:3000
open.execute(actionId, input, options?) // → output action
open.executeRaw(actionId, input, options?) // → { data, executionId, actionId, message }
open.<service>.<action>(input, options?) // namespace sugar для execute
open.health(options?) // → { ok, runtime }
open.catalog.action(actionId, options?) // → OpenActionMetadata
open.catalog.actions(service, options?) // → OpenActionMetadata[]
open.catalog.services(options?) // → string[] (service ids, у которых есть actions)
open.catalog.providers(query?, options?) // → ProviderMetadata[]
open.catalog.search(q, query?, options?) // → OpenActionSearchResult[] query: { service?, limit? }
open.apps.list(options?) // → ConnectedApp[]
open.apps.listByService(service, options?) // → ConnectedApp[]
open.apps.authenticated(services, options?) // → string[] (services с реальным credential)
options — { connectionName?, signal?, timeoutMs?, retries? } (без organization, без using()). config добавляет { baseUrl?, runtimeToken?, connectionName?, timeoutMs?, maxRetries?, fetch? }.
Экспортируемые сущности
import {
Connector,
ProjectConnector,
OpenConnector,
ConnectorError,
isRetryable,
} from "@oomol-lab/connector";
import type {
ClientConfig, CallOptions, ScopeOptions, RawResult,
ProxyRequest, ProxyResponse, ProxyMethod,
CatalogApi, ActionMetadata, ProviderMetadata, ProviderQuery,
AppsApi, ConnectedApp,
ConnectorErrorCode,
ProjectConnectorConfig, ProjectCallOptions, ProjectExecuteOptions,
ConnectionRequest, ConnectedAccount, ProviderSelector,
OAuthConnectInput, ApiKeyConnectInput, CustomCredentialConnectInput,
OpenConnectorConfig, OpenConnectorApi, OpenCallOptions, OpenExecuteOptions,
OpenCatalogApi, OpenAppsApi, OpenHealth,
OpenActionMetadata, OpenActionFollowUp, OpenActionAsyncLifecycle,
OpenActionSearchResult, OpenSearchQuery,
} from "@oomol-lab/connector";
Runnable и type-checked examples находятся в directory examples/ repository.
Лицензия
MIT, см. repository connector-sdk.