@tangle-network/agent-integrations 0.32.0 → 0.33.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin/tangle-catalog-runtime.js +7 -7
- package/dist/catalog.d.ts +74 -8
- package/dist/catalog.js +7 -7
- package/dist/{chunk-JCHD6L3B.js → chunk-43VQSANC.js} +2 -2
- package/dist/{chunk-F4YILONK.js → chunk-6N23S4JY.js} +21530 -257
- package/dist/chunk-6N23S4JY.js.map +1 -0
- package/dist/{chunk-VVC7U7W7.js → chunk-7T5YTVER.js} +51 -2
- package/dist/chunk-7T5YTVER.js.map +1 -0
- package/dist/{chunk-Q5X3QNHR.js → chunk-NQ7OPDUM.js} +261 -1
- package/dist/chunk-NQ7OPDUM.js.map +1 -0
- package/dist/{chunk-S2MVWQYL.js → chunk-RF3RH374.js} +2 -2
- package/dist/{chunk-DN6DNPPH.js → chunk-XO2RSS6Y.js} +125 -11
- package/dist/chunk-XO2RSS6Y.js.map +1 -0
- package/dist/{chunk-CDY2ETYT.js → chunk-YPZORI3G.js} +2 -2
- package/dist/connect/index.d.ts +2 -1
- package/dist/connect/index.js +2 -2
- package/dist/connectors/adapters/index.d.ts +113 -25
- package/dist/connectors/adapters/index.js +4 -2
- package/dist/connectors/index.d.ts +3 -2
- package/dist/connectors/index.js +4 -2
- package/dist/consumer-CzJgntej.d.ts +292 -0
- package/dist/consumer.d.ts +6 -8
- package/dist/consumer.js +2 -2
- package/dist/core-types-D5Dc65Ud.d.ts +355 -0
- package/dist/index.d.ts +1282 -4
- package/dist/index.js +13 -7
- package/dist/middleware/index.d.ts +2 -1
- package/dist/middleware/index.js +2 -2
- package/dist/registry.d.ts +3 -2424
- package/dist/registry.js +7 -7
- package/dist/runtime.d.ts +137 -8
- package/dist/runtime.js +7 -7
- package/dist/specs.d.ts +208 -8
- package/dist/specs.js +1 -1
- package/dist/tangle-catalog-runtime-2HddXxoM.d.ts +242 -0
- package/dist/tangle-catalog-runtime.d.ts +3 -8
- package/dist/tangle-catalog-runtime.js +7 -7
- package/dist/tangle-id-DA_qj-O_.d.ts +192 -0
- package/dist/{tangle-id-Dj0ipP4E.d.ts → types-XdpvaIzW.d.ts} +1 -167
- package/docs/integration-execution-audit.md +7 -5
- package/docs/integration-execution-matrix.json +32 -0
- package/package.json +12 -10
- package/dist/chunk-DN6DNPPH.js.map +0 -1
- package/dist/chunk-F4YILONK.js.map +0 -1
- package/dist/chunk-Q5X3QNHR.js.map +0 -1
- package/dist/chunk-VVC7U7W7.js.map +0 -1
- /package/dist/{chunk-JCHD6L3B.js.map → chunk-43VQSANC.js.map} +0 -0
- /package/dist/{chunk-S2MVWQYL.js.map → chunk-RF3RH374.js.map} +0 -0
- /package/dist/{chunk-CDY2ETYT.js.map → chunk-YPZORI3G.js.map} +0 -0
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import { I as IntegrationActor, e as IntegrationConnectorAction, g as IntegrationDataClass, i as IntegrationActionGuard, c as IntegrationConnection, j as IntegrationActionRequest, b as IntegrationConnector, k as IntegrationActionResult } from './core-types-D5Dc65Ud.js';
|
|
2
|
+
import { IntegrationSandboxBundle, IntegrationRequirementMode, IntegrationRequirementResolution, IntegrationManifest, IntegrationManifestResolution, IntegrationGrant } from './runtime.js';
|
|
3
|
+
import { IntegrationRegistry } from './registry.js';
|
|
4
|
+
|
|
5
|
+
type IntegrationAuditEventType = 'connection.created' | 'connection.updated' | 'connection.revoked' | 'grant.created' | 'grant.revoked' | 'capability.issued' | 'action.invoked' | 'action.failed' | 'trigger.subscribed' | 'trigger.received' | 'workflow.installed' | 'approval.requested' | 'approval.resolved' | 'healthcheck.completed';
|
|
6
|
+
interface IntegrationAuditEvent {
|
|
7
|
+
id: string;
|
|
8
|
+
type: IntegrationAuditEventType;
|
|
9
|
+
occurredAt: string;
|
|
10
|
+
actor?: IntegrationActor;
|
|
11
|
+
connectionId?: string;
|
|
12
|
+
providerId?: string;
|
|
13
|
+
connectorId?: string;
|
|
14
|
+
action?: string;
|
|
15
|
+
risk?: IntegrationConnectorAction['risk'];
|
|
16
|
+
dataClass?: IntegrationDataClass;
|
|
17
|
+
ok?: boolean;
|
|
18
|
+
message?: string;
|
|
19
|
+
metadata?: Record<string, unknown>;
|
|
20
|
+
}
|
|
21
|
+
interface IntegrationAuditSink {
|
|
22
|
+
record(event: IntegrationAuditEvent): Promise<void> | void;
|
|
23
|
+
}
|
|
24
|
+
interface IntegrationAuditStore extends IntegrationAuditSink {
|
|
25
|
+
list(filter?: IntegrationAuditFilter): Promise<IntegrationAuditEvent[]> | IntegrationAuditEvent[];
|
|
26
|
+
}
|
|
27
|
+
interface IntegrationAuditFilter {
|
|
28
|
+
type?: IntegrationAuditEventType;
|
|
29
|
+
actor?: IntegrationActor;
|
|
30
|
+
connectionId?: string;
|
|
31
|
+
providerId?: string;
|
|
32
|
+
connectorId?: string;
|
|
33
|
+
action?: string;
|
|
34
|
+
}
|
|
35
|
+
declare class InMemoryIntegrationAuditStore implements IntegrationAuditStore {
|
|
36
|
+
private readonly events;
|
|
37
|
+
record(event: IntegrationAuditEvent): void;
|
|
38
|
+
list(filter?: IntegrationAuditFilter): IntegrationAuditEvent[];
|
|
39
|
+
}
|
|
40
|
+
declare function createIntegrationAuditEvent(input: Omit<IntegrationAuditEvent, 'id' | 'occurredAt'> & {
|
|
41
|
+
id?: string;
|
|
42
|
+
occurredAt?: string | Date;
|
|
43
|
+
now?: () => Date;
|
|
44
|
+
}): IntegrationAuditEvent;
|
|
45
|
+
declare function createAuditingActionGuard(options: {
|
|
46
|
+
sink: IntegrationAuditSink;
|
|
47
|
+
subject?: IntegrationActor;
|
|
48
|
+
now?: () => Date;
|
|
49
|
+
includeInputPreview?: boolean;
|
|
50
|
+
}): IntegrationActionGuard;
|
|
51
|
+
declare function sanitizeAuditConnection(connection: IntegrationConnection): Record<string, unknown>;
|
|
52
|
+
|
|
53
|
+
type IntegrationHealthcheckStatus = 'healthy' | 'degraded' | 'unhealthy' | 'unknown';
|
|
54
|
+
interface IntegrationHealthcheckCheck {
|
|
55
|
+
id: string;
|
|
56
|
+
status: IntegrationHealthcheckStatus;
|
|
57
|
+
message: string;
|
|
58
|
+
metadata?: Record<string, unknown>;
|
|
59
|
+
}
|
|
60
|
+
interface IntegrationHealthcheckResult {
|
|
61
|
+
connectionId: string;
|
|
62
|
+
providerId: string;
|
|
63
|
+
connectorId: string;
|
|
64
|
+
status: IntegrationHealthcheckStatus;
|
|
65
|
+
checkedAt: string;
|
|
66
|
+
checks: IntegrationHealthcheckCheck[];
|
|
67
|
+
metadata?: Record<string, unknown>;
|
|
68
|
+
}
|
|
69
|
+
interface IntegrationHealthcheckStore {
|
|
70
|
+
put(result: IntegrationHealthcheckResult): Promise<void> | void;
|
|
71
|
+
get(connectionId: string): Promise<IntegrationHealthcheckResult | undefined> | IntegrationHealthcheckResult | undefined;
|
|
72
|
+
list(): Promise<IntegrationHealthcheckResult[]> | IntegrationHealthcheckResult[];
|
|
73
|
+
}
|
|
74
|
+
declare class InMemoryIntegrationHealthcheckStore implements IntegrationHealthcheckStore {
|
|
75
|
+
private readonly results;
|
|
76
|
+
put(result: IntegrationHealthcheckResult): void;
|
|
77
|
+
get(connectionId: string): IntegrationHealthcheckResult | undefined;
|
|
78
|
+
list(): IntegrationHealthcheckResult[];
|
|
79
|
+
}
|
|
80
|
+
declare function runIntegrationHealthcheck(input: {
|
|
81
|
+
connection: IntegrationConnection;
|
|
82
|
+
connector?: IntegrationConnector;
|
|
83
|
+
registry?: IntegrationRegistry;
|
|
84
|
+
test?: (connection: IntegrationConnection, connector: IntegrationConnector) => Promise<IntegrationActionResult | boolean> | IntegrationActionResult | boolean;
|
|
85
|
+
audit?: IntegrationAuditSink;
|
|
86
|
+
now?: () => Date;
|
|
87
|
+
}): Promise<IntegrationHealthcheckResult>;
|
|
88
|
+
declare function runIntegrationHealthchecks(input: {
|
|
89
|
+
connections: IntegrationConnection[];
|
|
90
|
+
registry?: IntegrationRegistry;
|
|
91
|
+
store?: IntegrationHealthcheckStore;
|
|
92
|
+
audit?: IntegrationAuditSink;
|
|
93
|
+
now?: () => Date;
|
|
94
|
+
test?: (connection: IntegrationConnection, connector: IntegrationConnector) => Promise<IntegrationActionResult | boolean> | IntegrationActionResult | boolean;
|
|
95
|
+
}): Promise<IntegrationHealthcheckResult[]>;
|
|
96
|
+
declare function healthcheckRequest(action?: string): IntegrationActionRequest;
|
|
97
|
+
|
|
98
|
+
/**
|
|
99
|
+
* @stable Integration Hub consumer client.
|
|
100
|
+
*
|
|
101
|
+
* The third client-shaped surface a product needs, alongside the two that
|
|
102
|
+
* already ship:
|
|
103
|
+
*
|
|
104
|
+
* - `createTangleIntegrationsClient` (`client.ts`) — the *invoke* client.
|
|
105
|
+
* Capability-token auth, runs INSIDE a sandbox / generated app, single
|
|
106
|
+
* endpoint `/v1/integrations/invoke`.
|
|
107
|
+
* - `startConnectFlow` / `finishConnectFlow` (`connect/index.ts`) — the
|
|
108
|
+
* *user-consent* flow, mirrors `/cross-site/*`.
|
|
109
|
+
* - **this** — the S2S *management* client. A product BACKEND (blueprint-
|
|
110
|
+
* agent, sandbox, gtm-agent, tax-agent, legal-agent, evals, …) drives the
|
|
111
|
+
* `/v1/integrations/{resolve-manifest,grants,capabilities/bundle,
|
|
112
|
+
* healthchecks/run}` management surface on `id.tangle.tools` on behalf of
|
|
113
|
+
* an identified user.
|
|
114
|
+
*
|
|
115
|
+
* Every consumer needs the identical client — the wire protocol, the
|
|
116
|
+
* `{ success, data }` envelope, the auth header shape are all platform-owned.
|
|
117
|
+
* Re-implementing a bespoke fetch loop per product forks the protocol and the
|
|
118
|
+
* copies drift. This module is that shared implementation. It mirrors the
|
|
119
|
+
* `connect/index.ts` design rule one-for-one: DO NOT invent the wire protocol
|
|
120
|
+
* — speak exactly what `products/platform/api/src/routes/integrations.ts`
|
|
121
|
+
* serves.
|
|
122
|
+
*
|
|
123
|
+
* Two auth modes — the route layer (`authMiddleware`) accepts either:
|
|
124
|
+
*
|
|
125
|
+
* - `service` — a `svc_*` service token + `X-Service-Name`. The acting
|
|
126
|
+
* user travels in `X-Platform-User-Id`. The platform honors that header
|
|
127
|
+
* only for service tokens whose `SERVICE_SCOPES` set contains
|
|
128
|
+
* `impersonate:user`; a token without it is rejected (403). Reaches the
|
|
129
|
+
* four management paths the platform allowlists for service tokens.
|
|
130
|
+
* - `user-key` — a per-user `sk-tan-*` API key (minted via the connect
|
|
131
|
+
* flow). The key identifies the user; no impersonation header. Reaches
|
|
132
|
+
* every route the user themselves can.
|
|
133
|
+
*
|
|
134
|
+
* The capability-token `invoke` endpoint is intentionally NOT exposed here —
|
|
135
|
+
* that is `createTangleIntegrationsClient`'s job and uses a different auth.
|
|
136
|
+
*/
|
|
137
|
+
|
|
138
|
+
type IntegrationHubAuth = {
|
|
139
|
+
mode: 'service';
|
|
140
|
+
/** The `svc_*` token issued to this product. */
|
|
141
|
+
serviceToken: string;
|
|
142
|
+
/** Registered service name — sent as `X-Service-Name`. Required
|
|
143
|
+
* because one token may be shared across services, in which case the
|
|
144
|
+
* platform demands the header to disambiguate. */
|
|
145
|
+
serviceName: string;
|
|
146
|
+
} | {
|
|
147
|
+
mode: 'user-key';
|
|
148
|
+
/** A per-user `sk-tan-*` key bound to the acting user. */
|
|
149
|
+
apiKey: string;
|
|
150
|
+
};
|
|
151
|
+
interface IntegrationHubClientOptions {
|
|
152
|
+
/** The product / consumer identifier (e.g. `blueprint-agent`). Sent as the
|
|
153
|
+
* `product` field of resolve-manifest calls; recorded platform-side. */
|
|
154
|
+
product: string;
|
|
155
|
+
/** Service-token or per-user-key auth. */
|
|
156
|
+
auth: IntegrationHubAuth;
|
|
157
|
+
/** Platform base URL. Defaults to `https://id.tangle.tools`. */
|
|
158
|
+
endpoint?: string;
|
|
159
|
+
/** Injected for tests. Defaults to the global `fetch`. */
|
|
160
|
+
fetchImpl?: typeof fetch;
|
|
161
|
+
/** Per-request timeout in ms. Default 10_000. */
|
|
162
|
+
timeoutMs?: number;
|
|
163
|
+
/** Max attempts on transient (network / 502 / 503 / 504) failures.
|
|
164
|
+
* Default 2 — i.e. one retry. */
|
|
165
|
+
maxAttempts?: number;
|
|
166
|
+
}
|
|
167
|
+
/** Thrown for every non-2xx response and every transport failure. Carries the
|
|
168
|
+
* HTTP status and the platform error code so callers can branch precisely
|
|
169
|
+
* (`403` + `impersonate` → the service token lacks the scope; `409` /
|
|
170
|
+
* `missing_connection` → prompt the user to connect). */
|
|
171
|
+
declare class IntegrationHubRequestError extends Error {
|
|
172
|
+
readonly name = "IntegrationHubRequestError";
|
|
173
|
+
/** HTTP status, or 0 for a network-level failure. */
|
|
174
|
+
readonly status: number;
|
|
175
|
+
/** Platform error code (`VALIDATION_ERROR`, `scope_missing`, …) or
|
|
176
|
+
* `network_error` / `http_error` when no structured code was returned. */
|
|
177
|
+
readonly code: string;
|
|
178
|
+
/** `METHOD /path` the request targeted. */
|
|
179
|
+
readonly endpoint: string;
|
|
180
|
+
/** True when the failure class is transient and a retry could succeed. */
|
|
181
|
+
readonly retryable: boolean;
|
|
182
|
+
constructor(input: {
|
|
183
|
+
status: number;
|
|
184
|
+
code: string;
|
|
185
|
+
message: string;
|
|
186
|
+
endpoint: string;
|
|
187
|
+
retryable: boolean;
|
|
188
|
+
});
|
|
189
|
+
}
|
|
190
|
+
interface ResolveManifestInput {
|
|
191
|
+
/** The acting user — the connection owner. */
|
|
192
|
+
userId: string;
|
|
193
|
+
manifest: IntegrationManifest;
|
|
194
|
+
/** Overrides the client-level `product` for this call. */
|
|
195
|
+
product?: string;
|
|
196
|
+
}
|
|
197
|
+
interface CreateGrantsInput {
|
|
198
|
+
/** The acting user — the connection owner. */
|
|
199
|
+
userId: string;
|
|
200
|
+
/** Who the grant is FOR (the sandbox / agent / app that will invoke). */
|
|
201
|
+
grantee: IntegrationActor;
|
|
202
|
+
manifest: IntegrationManifest;
|
|
203
|
+
metadata?: Record<string, unknown>;
|
|
204
|
+
}
|
|
205
|
+
interface ListGrantsInput {
|
|
206
|
+
/** The acting user — the connection owner. */
|
|
207
|
+
userId: string;
|
|
208
|
+
/** Optional grantee filter; both fields travel together as query params. */
|
|
209
|
+
grantee?: IntegrationActor;
|
|
210
|
+
}
|
|
211
|
+
interface MintCapabilityBundleInput {
|
|
212
|
+
/** The acting user — must own every connection behind the grants. */
|
|
213
|
+
userId: string;
|
|
214
|
+
/** Who the capability bundle is issued TO (the sandbox / agent process). */
|
|
215
|
+
subject: IntegrationActor;
|
|
216
|
+
/** Mint from every grant of a manifest … */
|
|
217
|
+
manifestId?: string;
|
|
218
|
+
/** … or from an explicit grant id list. Exactly one of the two is required. */
|
|
219
|
+
grantIds?: string[];
|
|
220
|
+
grantee?: IntegrationActor;
|
|
221
|
+
/** Bundle TTL in ms. Platform clamps to [1s, 60m]; default 15m. */
|
|
222
|
+
ttlMs?: number;
|
|
223
|
+
}
|
|
224
|
+
interface CapabilityBundleResult {
|
|
225
|
+
bundle: IntegrationSandboxBundle;
|
|
226
|
+
/** Bridge environment variables to inject into the sandbox process —
|
|
227
|
+
* `buildIntegrationBridgeEnvironment(bundle)`, computed platform-side. */
|
|
228
|
+
env: Record<string, string>;
|
|
229
|
+
}
|
|
230
|
+
interface CheckConnectorInput {
|
|
231
|
+
/** The acting user. */
|
|
232
|
+
userId: string;
|
|
233
|
+
/** Connector to probe — `github`, `google-calendar`, `tangle-id`, … */
|
|
234
|
+
connectorId: string;
|
|
235
|
+
/** Defaults to `read`. */
|
|
236
|
+
mode?: IntegrationRequirementMode;
|
|
237
|
+
requiredScopes?: string[];
|
|
238
|
+
requiredActions?: string[];
|
|
239
|
+
}
|
|
240
|
+
interface CheckConnectorResult {
|
|
241
|
+
/** True when the user has an active connection satisfying the requirement. */
|
|
242
|
+
connected: boolean;
|
|
243
|
+
/** The satisfying connection, present iff `connected`. */
|
|
244
|
+
connection?: IntegrationConnection;
|
|
245
|
+
/** The full requirement resolution — status, missing scopes/actions, message. */
|
|
246
|
+
resolution: IntegrationRequirementResolution;
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* S2S management client for the `id.tangle.tools` integration hub. One per
|
|
250
|
+
* product; methods are stateless and safe to call concurrently.
|
|
251
|
+
*/
|
|
252
|
+
declare class IntegrationHubClient {
|
|
253
|
+
private readonly endpoint;
|
|
254
|
+
private readonly product;
|
|
255
|
+
private readonly auth;
|
|
256
|
+
private readonly fetchImpl;
|
|
257
|
+
private readonly timeoutMs;
|
|
258
|
+
private readonly maxAttempts;
|
|
259
|
+
constructor(options: IntegrationHubClientOptions);
|
|
260
|
+
/**
|
|
261
|
+
* Resolve a manifest against a user's connections. The returned
|
|
262
|
+
* `ready` / `missing` split is the canonical way to ask "does this user
|
|
263
|
+
* have the connections this work needs" — the raw connection list is not
|
|
264
|
+
* reachable by a service token by design.
|
|
265
|
+
*/
|
|
266
|
+
resolveManifest(input: ResolveManifestInput): Promise<IntegrationManifestResolution>;
|
|
267
|
+
/**
|
|
268
|
+
* Convenience over {@link resolveManifest} — probe a single connector and
|
|
269
|
+
* get back a boolean plus the satisfying connection. The Surface-A quest
|
|
270
|
+
* primitive ("is the user's GitHub linked?").
|
|
271
|
+
*/
|
|
272
|
+
checkConnector(input: CheckConnectorInput): Promise<CheckConnectorResult>;
|
|
273
|
+
/** Create grants for every satisfiable requirement of a manifest. The
|
|
274
|
+
* platform rejects the call if any non-optional requirement is missing a
|
|
275
|
+
* connection. */
|
|
276
|
+
createGrants(input: CreateGrantsInput): Promise<IntegrationGrant[]>;
|
|
277
|
+
/** List the acting user's grants, optionally filtered to one grantee. */
|
|
278
|
+
listGrants(input: ListGrantsInput): Promise<IntegrationGrant[]>;
|
|
279
|
+
/** Mint a short-lived capability bundle for a sandbox / agent process.
|
|
280
|
+
* Provider credentials never leave the platform — the bundle carries only
|
|
281
|
+
* scoped, expiring capability tokens. */
|
|
282
|
+
mintCapabilityBundle(input: MintCapabilityBundleInput): Promise<CapabilityBundleResult>;
|
|
283
|
+
/** Run live healthchecks across all of the acting user's connections. */
|
|
284
|
+
runHealthchecks(input: {
|
|
285
|
+
userId: string;
|
|
286
|
+
}): Promise<IntegrationHealthcheckResult[]>;
|
|
287
|
+
private buildHeaders;
|
|
288
|
+
private request;
|
|
289
|
+
}
|
|
290
|
+
declare function createIntegrationHubClient(options: IntegrationHubClientOptions): IntegrationHubClient;
|
|
291
|
+
|
|
292
|
+
export { type CapabilityBundleResult as C, type IntegrationAuditSink as I, type ListGrantsInput as L, type MintCapabilityBundleInput as M, type ResolveManifestInput as R, type CheckConnectorInput as a, type CheckConnectorResult as b, type CreateGrantsInput as c, InMemoryIntegrationAuditStore as d, InMemoryIntegrationHealthcheckStore as e, type IntegrationAuditEvent as f, type IntegrationAuditEventType as g, type IntegrationAuditFilter as h, type IntegrationAuditStore as i, type IntegrationHealthcheckCheck as j, type IntegrationHealthcheckResult as k, type IntegrationHealthcheckStatus as l, type IntegrationHealthcheckStore as m, type IntegrationHubAuth as n, IntegrationHubClient as o, type IntegrationHubClientOptions as p, IntegrationHubRequestError as q, createAuditingActionGuard as r, createIntegrationAuditEvent as s, createIntegrationHubClient as t, healthcheckRequest as u, runIntegrationHealthcheck as v, runIntegrationHealthchecks as w, sanitizeAuditConnection as x };
|
package/dist/consumer.d.ts
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import './
|
|
3
|
-
|
|
4
|
-
import './
|
|
5
|
-
import './
|
|
6
|
-
import './
|
|
7
|
-
import './connectors/adapters/index.js';
|
|
8
|
-
import 'node:http';
|
|
1
|
+
import './core-types-D5Dc65Ud.js';
|
|
2
|
+
import './runtime.js';
|
|
3
|
+
export { C as CapabilityBundleResult, a as CheckConnectorInput, b as CheckConnectorResult, c as CreateGrantsInput, n as IntegrationHubAuth, o as IntegrationHubClient, p as IntegrationHubClientOptions, q as IntegrationHubRequestError, L as ListGrantsInput, M as MintCapabilityBundleInput, R as ResolveManifestInput, t as createIntegrationHubClient } from './consumer-CzJgntej.js';
|
|
4
|
+
import './types-XdpvaIzW.js';
|
|
5
|
+
import './catalog.js';
|
|
6
|
+
import './registry.js';
|
package/dist/consumer.js
CHANGED
|
@@ -2,8 +2,8 @@ import {
|
|
|
2
2
|
IntegrationHubClient,
|
|
3
3
|
IntegrationHubRequestError,
|
|
4
4
|
createIntegrationHubClient
|
|
5
|
-
} from "./chunk-
|
|
6
|
-
import "./chunk-
|
|
5
|
+
} from "./chunk-RF3RH374.js";
|
|
6
|
+
import "./chunk-NQ7OPDUM.js";
|
|
7
7
|
export {
|
|
8
8
|
IntegrationHubClient,
|
|
9
9
|
IntegrationHubRequestError,
|
|
@@ -0,0 +1,355 @@
|
|
|
1
|
+
import { a as ConnectorCredentials } from './types-XdpvaIzW.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vendor-neutral integration contracts.
|
|
5
|
+
*
|
|
6
|
+
* Pure type module: every interface, type alias, and enum that other
|
|
7
|
+
* source files reference lives here. Holds zero runtime symbols so any
|
|
8
|
+
* module can import from it without forming a cycle through the package
|
|
9
|
+
* barrel (`./index.ts`).
|
|
10
|
+
*
|
|
11
|
+
* Runtime classes (`IntegrationError`, `InMemoryConnectionStore`,
|
|
12
|
+
* `IntegrationHub`, helpers) stay in `./index.ts` or are split out into
|
|
13
|
+
* their own focused modules (`./core-error.ts`).
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
type IntegrationProviderKind = 'first_party' | 'nango' | 'pipedream' | 'zapier' | 'activepieces' | 'tangle_catalog' | 'executor' | 'custom';
|
|
17
|
+
type IntegrationConnectorCategory = 'email' | 'calendar' | 'chat' | 'crm' | 'storage' | 'docs' | 'database' | 'webhook' | 'workflow' | 'internal' | 'other';
|
|
18
|
+
type IntegrationActionRisk = 'read' | 'write' | 'destructive';
|
|
19
|
+
type IntegrationDataClass = 'public' | 'internal' | 'private' | 'sensitive' | 'secret';
|
|
20
|
+
interface IntegrationActor {
|
|
21
|
+
type: 'user' | 'team' | 'app' | 'agent' | 'sandbox' | 'system';
|
|
22
|
+
id: string;
|
|
23
|
+
}
|
|
24
|
+
interface IntegrationConnectorAction {
|
|
25
|
+
id: string;
|
|
26
|
+
title: string;
|
|
27
|
+
risk: IntegrationActionRisk;
|
|
28
|
+
requiredScopes: string[];
|
|
29
|
+
dataClass: IntegrationDataClass;
|
|
30
|
+
description?: string;
|
|
31
|
+
approvalRequired?: boolean;
|
|
32
|
+
inputSchema?: unknown;
|
|
33
|
+
outputSchema?: unknown;
|
|
34
|
+
}
|
|
35
|
+
interface IntegrationConnectorTrigger {
|
|
36
|
+
id: string;
|
|
37
|
+
title: string;
|
|
38
|
+
requiredScopes: string[];
|
|
39
|
+
dataClass: IntegrationDataClass;
|
|
40
|
+
description?: string;
|
|
41
|
+
payloadSchema?: unknown;
|
|
42
|
+
}
|
|
43
|
+
interface IntegrationConnector {
|
|
44
|
+
id: string;
|
|
45
|
+
providerId: string;
|
|
46
|
+
title: string;
|
|
47
|
+
category: IntegrationConnectorCategory;
|
|
48
|
+
auth: 'oauth2' | 'api_key' | 'none' | 'custom';
|
|
49
|
+
scopes: string[];
|
|
50
|
+
actions: IntegrationConnectorAction[];
|
|
51
|
+
triggers?: IntegrationConnectorTrigger[];
|
|
52
|
+
metadata?: Record<string, unknown>;
|
|
53
|
+
}
|
|
54
|
+
interface SecretRef {
|
|
55
|
+
provider: string;
|
|
56
|
+
id: string;
|
|
57
|
+
label?: string;
|
|
58
|
+
}
|
|
59
|
+
interface IntegrationConnection {
|
|
60
|
+
id: string;
|
|
61
|
+
owner: IntegrationActor;
|
|
62
|
+
providerId: string;
|
|
63
|
+
connectorId: string;
|
|
64
|
+
status: 'pending' | 'active' | 'expired' | 'revoked' | 'error';
|
|
65
|
+
grantedScopes: string[];
|
|
66
|
+
account?: {
|
|
67
|
+
id?: string;
|
|
68
|
+
email?: string;
|
|
69
|
+
displayName?: string;
|
|
70
|
+
};
|
|
71
|
+
secretRef?: SecretRef;
|
|
72
|
+
createdAt: string;
|
|
73
|
+
updatedAt: string;
|
|
74
|
+
expiresAt?: string;
|
|
75
|
+
lastUsedAt?: string;
|
|
76
|
+
metadata?: Record<string, unknown>;
|
|
77
|
+
}
|
|
78
|
+
interface StartAuthRequest {
|
|
79
|
+
connectorId: string;
|
|
80
|
+
owner: IntegrationActor;
|
|
81
|
+
requestedScopes: string[];
|
|
82
|
+
redirectUri: string;
|
|
83
|
+
state?: string;
|
|
84
|
+
metadata?: Record<string, unknown>;
|
|
85
|
+
}
|
|
86
|
+
interface StartAuthResult {
|
|
87
|
+
providerId: string;
|
|
88
|
+
connectorId: string;
|
|
89
|
+
authUrl: string;
|
|
90
|
+
state: string;
|
|
91
|
+
expiresAt?: string;
|
|
92
|
+
metadata?: Record<string, unknown>;
|
|
93
|
+
}
|
|
94
|
+
interface CompleteAuthRequest {
|
|
95
|
+
connectorId: string;
|
|
96
|
+
owner: IntegrationActor;
|
|
97
|
+
code?: string;
|
|
98
|
+
state: string;
|
|
99
|
+
redirectUri: string;
|
|
100
|
+
metadata?: Record<string, unknown>;
|
|
101
|
+
}
|
|
102
|
+
interface IntegrationActionRequest {
|
|
103
|
+
connectionId: string;
|
|
104
|
+
action: string;
|
|
105
|
+
input?: unknown;
|
|
106
|
+
idempotencyKey?: string;
|
|
107
|
+
dryRun?: boolean;
|
|
108
|
+
metadata?: Record<string, unknown>;
|
|
109
|
+
}
|
|
110
|
+
interface IntegrationActionResult<T = unknown> {
|
|
111
|
+
ok: boolean;
|
|
112
|
+
action: string;
|
|
113
|
+
output?: T;
|
|
114
|
+
externalId?: string;
|
|
115
|
+
warnings?: string[];
|
|
116
|
+
metadata?: Record<string, unknown>;
|
|
117
|
+
}
|
|
118
|
+
interface IntegrationTriggerSubscription {
|
|
119
|
+
id: string;
|
|
120
|
+
connectionId: string;
|
|
121
|
+
trigger: string;
|
|
122
|
+
targetUrl?: string;
|
|
123
|
+
status: 'active' | 'paused' | 'error';
|
|
124
|
+
createdAt: string;
|
|
125
|
+
metadata?: Record<string, unknown>;
|
|
126
|
+
}
|
|
127
|
+
interface IntegrationTriggerEvent<T = unknown> {
|
|
128
|
+
id: string;
|
|
129
|
+
providerId: string;
|
|
130
|
+
connectorId: string;
|
|
131
|
+
connectionId: string;
|
|
132
|
+
trigger: string;
|
|
133
|
+
occurredAt: string;
|
|
134
|
+
payload: T;
|
|
135
|
+
metadata?: Record<string, unknown>;
|
|
136
|
+
}
|
|
137
|
+
interface IntegrationProvider {
|
|
138
|
+
id: string;
|
|
139
|
+
kind: IntegrationProviderKind;
|
|
140
|
+
listConnectors(): Promise<IntegrationConnector[]> | IntegrationConnector[];
|
|
141
|
+
startAuth?(request: StartAuthRequest): Promise<StartAuthResult> | StartAuthResult;
|
|
142
|
+
completeAuth?(request: CompleteAuthRequest): Promise<IntegrationConnection> | IntegrationConnection;
|
|
143
|
+
invokeAction(connection: IntegrationConnection, request: IntegrationActionRequest): Promise<IntegrationActionResult> | IntegrationActionResult;
|
|
144
|
+
subscribeTrigger?(connection: IntegrationConnection, trigger: string, targetUrl?: string): Promise<IntegrationTriggerSubscription> | IntegrationTriggerSubscription;
|
|
145
|
+
unsubscribeTrigger?(subscriptionId: string): Promise<void> | void;
|
|
146
|
+
normalizeTriggerEvent?(raw: unknown): Promise<IntegrationTriggerEvent> | IntegrationTriggerEvent;
|
|
147
|
+
}
|
|
148
|
+
interface IntegrationConnectionStore {
|
|
149
|
+
get(connectionId: string): Promise<IntegrationConnection | undefined> | IntegrationConnection | undefined;
|
|
150
|
+
put(connection: IntegrationConnection): Promise<void> | void;
|
|
151
|
+
listByOwner(owner: IntegrationActor): Promise<IntegrationConnection[]> | IntegrationConnection[];
|
|
152
|
+
delete?(connectionId: string): Promise<void> | void;
|
|
153
|
+
}
|
|
154
|
+
interface IssueCapabilityRequest {
|
|
155
|
+
subject: IntegrationActor;
|
|
156
|
+
connectionId: string;
|
|
157
|
+
scopes: string[];
|
|
158
|
+
allowedActions: string[];
|
|
159
|
+
ttlMs: number;
|
|
160
|
+
metadata?: Record<string, unknown>;
|
|
161
|
+
}
|
|
162
|
+
interface IntegrationCapability {
|
|
163
|
+
id: string;
|
|
164
|
+
subject: IntegrationActor;
|
|
165
|
+
connectionId: string;
|
|
166
|
+
scopes: string[];
|
|
167
|
+
allowedActions: string[];
|
|
168
|
+
issuedAt: string;
|
|
169
|
+
expiresAt: string;
|
|
170
|
+
metadata?: Record<string, unknown>;
|
|
171
|
+
}
|
|
172
|
+
interface IssuedIntegrationCapability {
|
|
173
|
+
capability: IntegrationCapability;
|
|
174
|
+
token: string;
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Wraps every action invocation with cross-cutting discipline (idempotency,
|
|
178
|
+
* conflict detection, rate-limiting, audit logging). Optional. When set on
|
|
179
|
+
* the hub, runs BEFORE provider.invokeAction; can short-circuit (return a
|
|
180
|
+
* result directly) or pass through (call `proceed()` to invoke the provider).
|
|
181
|
+
*
|
|
182
|
+
* Why this hook exists: production deployments need conflict-resolution
|
|
183
|
+
* guarantees that span every provider, gateway, and webhook receiver. The
|
|
184
|
+
* canonical implementation is a "MutationGuard" that:
|
|
185
|
+
* 1. Short-circuits on a known idempotency key (returns recorded response).
|
|
186
|
+
* 2. Refuses same-key-different-args (drift detection).
|
|
187
|
+
* 3. Wraps `proceed()` and audit-logs the outcome.
|
|
188
|
+
* 4. Translates upstream conflict signals into a structured result with
|
|
189
|
+
* alternatives the agent can act on.
|
|
190
|
+
*
|
|
191
|
+
* Implementations live in consumers (every product has different
|
|
192
|
+
* persistence + telemetry needs); this interface is the contract.
|
|
193
|
+
*/
|
|
194
|
+
interface IntegrationActionGuard {
|
|
195
|
+
/** Wrap an invokeAction call. Implementations MUST call `proceed()` to
|
|
196
|
+
* invoke the underlying provider unless they're returning a cached or
|
|
197
|
+
* short-circuited result.
|
|
198
|
+
*
|
|
199
|
+
* @param ctx connection + request the hub is about to dispatch
|
|
200
|
+
* @param proceed call to invoke the wrapped provider; returns the
|
|
201
|
+
* underlying IntegrationActionResult
|
|
202
|
+
* @returns the result the hub should return to the caller
|
|
203
|
+
*/
|
|
204
|
+
invokeAction(ctx: IntegrationGuardContext, proceed: () => Promise<IntegrationActionResult>): Promise<IntegrationActionResult>;
|
|
205
|
+
}
|
|
206
|
+
interface IntegrationGuardContext {
|
|
207
|
+
connection: IntegrationConnection;
|
|
208
|
+
request: IntegrationActionRequest;
|
|
209
|
+
/** The action descriptor from the connector manifest, if discovered. */
|
|
210
|
+
action?: IntegrationConnectorAction;
|
|
211
|
+
}
|
|
212
|
+
type IntegrationPolicyDecision = {
|
|
213
|
+
decision: 'allow';
|
|
214
|
+
reason: string;
|
|
215
|
+
metadata?: Record<string, unknown>;
|
|
216
|
+
} | {
|
|
217
|
+
decision: 'require_approval';
|
|
218
|
+
reason: string;
|
|
219
|
+
approval: IntegrationApprovalRequest;
|
|
220
|
+
metadata?: Record<string, unknown>;
|
|
221
|
+
} | {
|
|
222
|
+
decision: 'deny';
|
|
223
|
+
reason: string;
|
|
224
|
+
metadata?: Record<string, unknown>;
|
|
225
|
+
};
|
|
226
|
+
interface IntegrationApprovalRequest {
|
|
227
|
+
id: string;
|
|
228
|
+
connectionId: string;
|
|
229
|
+
providerId: string;
|
|
230
|
+
connectorId: string;
|
|
231
|
+
action: string;
|
|
232
|
+
actor: IntegrationActor;
|
|
233
|
+
risk: IntegrationActionRisk;
|
|
234
|
+
dataClass: IntegrationDataClass;
|
|
235
|
+
reason: string;
|
|
236
|
+
requestedAt: string;
|
|
237
|
+
inputPreview?: unknown;
|
|
238
|
+
metadata?: Record<string, unknown>;
|
|
239
|
+
}
|
|
240
|
+
interface IntegrationPolicyEngine {
|
|
241
|
+
decide(ctx: IntegrationGuardContext & {
|
|
242
|
+
subject: IntegrationActor;
|
|
243
|
+
}): Promise<IntegrationPolicyDecision> | IntegrationPolicyDecision;
|
|
244
|
+
}
|
|
245
|
+
interface IntegrationHubOptions {
|
|
246
|
+
providers: IntegrationProvider[];
|
|
247
|
+
store: IntegrationConnectionStore;
|
|
248
|
+
capabilitySecret: string;
|
|
249
|
+
/** Optional cross-cutting guard. If provided, every invokeAction call
|
|
250
|
+
* passes through it before reaching the provider. See {@link IntegrationActionGuard}. */
|
|
251
|
+
guard?: IntegrationActionGuard;
|
|
252
|
+
/** Optional policy engine. Runs after capability/scope checks and before
|
|
253
|
+
* provider invocation. Use it to pause writes, deny destructive actions,
|
|
254
|
+
* or apply tenant-specific allow rules. */
|
|
255
|
+
policy?: IntegrationPolicyEngine;
|
|
256
|
+
/** Host-injectable secret store. Multi-tenant hubs inject a durable
|
|
257
|
+
* encrypted store; defaults to InMemoryIntegrationSecretStore for
|
|
258
|
+
* local/dev and tests. The interface is the contract — the lib never
|
|
259
|
+
* ships a D1/KV/encryption impl. */
|
|
260
|
+
secretStore?: IntegrationSecretStore;
|
|
261
|
+
/** Host-injectable single-use OAuth-state store guarding the start →
|
|
262
|
+
* callback CSRF boundary. Defaults to InMemoryIntegrationOAuthStateStore. */
|
|
263
|
+
oauthStateStore?: IntegrationOAuthStateStore;
|
|
264
|
+
/** TTL applied to OAuth-state records the hub stashes at startAuth.
|
|
265
|
+
* Defaults to 10 minutes. */
|
|
266
|
+
oauthStateTtlMs?: number;
|
|
267
|
+
/** Fired whenever a provider surfaces rotated credentials during an
|
|
268
|
+
* invoke (e.g. an OAuth access token refreshed on expiry). The host
|
|
269
|
+
* re-encrypts + persists the rotated envelope so the next expiry does
|
|
270
|
+
* not force a reconnect. The hub also writes the rotated credentials to
|
|
271
|
+
* {@link secretStore} when the connection carries a secretRef. */
|
|
272
|
+
credentialsRotated?: (event: IntegrationCredentialsRotatedEvent) => Promise<void> | void;
|
|
273
|
+
now?: () => Date;
|
|
274
|
+
}
|
|
275
|
+
/** Emitted when a provider rotates credentials mid-invoke. The host
|
|
276
|
+
* re-persists `credentials` against `secretRef` (when present) so the
|
|
277
|
+
* refreshed token survives the call. */
|
|
278
|
+
interface IntegrationCredentialsRotatedEvent {
|
|
279
|
+
connection: IntegrationConnection;
|
|
280
|
+
secretRef?: SecretRef;
|
|
281
|
+
credentials: ConnectorCredentials;
|
|
282
|
+
}
|
|
283
|
+
interface HttpIntegrationProviderOptions {
|
|
284
|
+
id: string;
|
|
285
|
+
kind?: IntegrationProviderKind;
|
|
286
|
+
connectors: IntegrationConnector[];
|
|
287
|
+
baseUrl: string;
|
|
288
|
+
bearer?: string;
|
|
289
|
+
fetchImpl?: typeof fetch;
|
|
290
|
+
}
|
|
291
|
+
interface InvokeWithCapabilityRequest extends Omit<IntegrationActionRequest, 'connectionId'> {
|
|
292
|
+
connectionId?: never;
|
|
293
|
+
}
|
|
294
|
+
/** A catalog of connectors keyed by stable source id. The registry merges
|
|
295
|
+
* multiple sources (first-party adapter packs, Activepieces import, custom
|
|
296
|
+
* HTTP catalog, …) into a canonical view with conflict reporting. */
|
|
297
|
+
interface IntegrationCatalogSource {
|
|
298
|
+
id: string;
|
|
299
|
+
connectors: IntegrationConnector[];
|
|
300
|
+
precedence?: number;
|
|
301
|
+
}
|
|
302
|
+
/** Host-injectable persistent store for OAuth tokens and other connector
|
|
303
|
+
* credentials. Multi-tenant hubs inject a durable encrypted store; defaults
|
|
304
|
+
* to an in-memory implementation for local/dev and tests. The interface is
|
|
305
|
+
* the contract — the lib never ships a D1/KV/encryption impl. */
|
|
306
|
+
interface IntegrationSecretStore {
|
|
307
|
+
get(ref: SecretRef): Promise<ConnectorCredentials | undefined> | ConnectorCredentials | undefined;
|
|
308
|
+
put(ref: SecretRef, credentials: ConnectorCredentials): Promise<void> | void;
|
|
309
|
+
delete?(ref: SecretRef): Promise<void> | void;
|
|
310
|
+
}
|
|
311
|
+
/** Single-use record stashed at OAuth-start and consumed once at callback to
|
|
312
|
+
* guard against CSRF / replay. The hub injects its own durable
|
|
313
|
+
* implementation (KV/Redis/D1) so the callback can land on any worker. */
|
|
314
|
+
interface IntegrationOAuthState {
|
|
315
|
+
/** Opaque value round-tripped through the provider redirect. */
|
|
316
|
+
state: string;
|
|
317
|
+
/** Provider the auth flow targets. */
|
|
318
|
+
providerId: string;
|
|
319
|
+
/** Connector the user is connecting. */
|
|
320
|
+
connectorId: string;
|
|
321
|
+
/** Owner initiating the flow. */
|
|
322
|
+
owner: IntegrationActor;
|
|
323
|
+
/** Scopes requested at start; verified against the granted scopes on callback. */
|
|
324
|
+
requestedScopes: string[];
|
|
325
|
+
/** Redirect URI used at start; MUST match exactly on callback exchange. */
|
|
326
|
+
redirectUri: string;
|
|
327
|
+
/** PKCE code_verifier, when the connector uses PKCE. */
|
|
328
|
+
codeVerifier?: string;
|
|
329
|
+
/** Absolute expiry (UTC ms since epoch). consume() MUST treat an expired
|
|
330
|
+
* record as a miss. */
|
|
331
|
+
expiresAt: number;
|
|
332
|
+
/** Arbitrary non-secret context the host pinned at start-time. */
|
|
333
|
+
metadata?: Record<string, unknown>;
|
|
334
|
+
}
|
|
335
|
+
/** Outcome of consuming an OAuth state record. Callers MUST inspect `ok`
|
|
336
|
+
* before using `state`; a miss (`unknown`/`expired`) is the CSRF/replay
|
|
337
|
+
* guard firing, not an exception. */
|
|
338
|
+
type IntegrationOAuthStateOutcome = {
|
|
339
|
+
ok: true;
|
|
340
|
+
state: IntegrationOAuthState;
|
|
341
|
+
} | {
|
|
342
|
+
ok: false;
|
|
343
|
+
reason: 'unknown' | 'expired';
|
|
344
|
+
};
|
|
345
|
+
/** Host-injectable store for single-use OAuth-start records. The default is
|
|
346
|
+
* in-memory for local/dev and tests; multi-tenant hubs inject a durable
|
|
347
|
+
* encrypted store so callbacks survive worker hops. consume() MUST be
|
|
348
|
+
* single-use: a second consume of the same state returns `{ ok: false }`. */
|
|
349
|
+
interface IntegrationOAuthStateStore {
|
|
350
|
+
put(state: IntegrationOAuthState): Promise<void> | void;
|
|
351
|
+
consume(state: string): Promise<IntegrationOAuthStateOutcome> | IntegrationOAuthStateOutcome;
|
|
352
|
+
sweep?(now: number): Promise<void> | void;
|
|
353
|
+
}
|
|
354
|
+
|
|
355
|
+
export type { IntegrationTriggerEvent as A, InvokeWithCapabilityRequest as B, CompleteAuthRequest as C, IntegrationCapability as D, IntegrationHubOptions as E, IssueCapabilityRequest as F, IntegrationConnectorTrigger as G, HttpIntegrationProviderOptions as H, IntegrationActor as I, StartAuthRequest as S, IssuedIntegrationCapability as a, IntegrationConnector as b, IntegrationConnection as c, IntegrationConnectorCategory as d, IntegrationConnectorAction as e, IntegrationActionRisk as f, IntegrationDataClass as g, IntegrationCatalogSource as h, IntegrationActionGuard as i, IntegrationActionRequest as j, IntegrationActionResult as k, StartAuthResult as l, IntegrationProvider as m, IntegrationSecretStore as n, IntegrationPolicyEngine as o, IntegrationApprovalRequest as p, IntegrationGuardContext as q, IntegrationPolicyDecision as r, IntegrationProviderKind as s, IntegrationConnectionStore as t, IntegrationCredentialsRotatedEvent as u, IntegrationOAuthStateStore as v, IntegrationOAuthState as w, IntegrationOAuthStateOutcome as x, SecretRef as y, IntegrationTriggerSubscription as z };
|