@tangle-network/agent-integrations 0.13.0 → 0.14.0
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/README.md +48 -0
- package/dist/index.d.ts +197 -1
- package/dist/index.js +327 -20
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -128,21 +128,24 @@ function buildActivepiecesConnectors(options = {}) {
|
|
|
128
128
|
const override = getActivepiecesOverride(entry.id);
|
|
129
129
|
const category = override?.category ?? entry.category;
|
|
130
130
|
const scopes = [`${entry.id}.read`, `${entry.id}.write`];
|
|
131
|
-
const
|
|
131
|
+
const catalogActions = entry.actions.length > 0 ? entry.actions.map((action) => toAction(applyActionOverride(action, override), scopes, dataClassFor(category))) : defaultActions(entry.id, scopes, dataClassFor(category));
|
|
132
|
+
const catalogTriggers = entry.triggers.map((trigger) => toTrigger(trigger, scopes, dataClassFor(category)));
|
|
132
133
|
return {
|
|
133
134
|
id: entry.id,
|
|
134
135
|
providerId,
|
|
135
136
|
title: entry.title,
|
|
136
137
|
category,
|
|
137
138
|
auth: entry.auth,
|
|
138
|
-
scopes,
|
|
139
|
-
actions,
|
|
140
|
-
triggers:
|
|
139
|
+
scopes: options.includeCatalogActions ? scopes : [],
|
|
140
|
+
actions: options.includeCatalogActions ? catalogActions : [],
|
|
141
|
+
triggers: options.includeCatalogActions ? catalogTriggers : void 0,
|
|
141
142
|
metadata: {
|
|
142
143
|
source: "activepieces-community",
|
|
143
144
|
executable: false,
|
|
144
145
|
runtime: "activepieces-piece",
|
|
145
146
|
catalogOnly: true,
|
|
147
|
+
catalogActionCount: catalogActions.length,
|
|
148
|
+
catalogTriggerCount: catalogTriggers.length,
|
|
146
149
|
npmPackage: entry.npmPackage,
|
|
147
150
|
version: entry.version,
|
|
148
151
|
license: entry.source.license,
|
|
@@ -490,15 +493,15 @@ function actionPack(pack, scopes) {
|
|
|
490
493
|
}
|
|
491
494
|
function triggersFor(pack, scopes) {
|
|
492
495
|
const readScope = scopes.find((scope) => scope.endsWith(".read")) ?? scopes[0];
|
|
493
|
-
const
|
|
494
|
-
if (pack === "email") return [{ id: "message.received", title: "Message received", requiredScopes, dataClass: "private" }];
|
|
495
|
-
if (pack === "calendar") return [{ id: "event.changed", title: "Event changed", requiredScopes, dataClass: "private" }];
|
|
496
|
-
if (pack === "chat") return [{ id: "message.posted", title: "Message posted", requiredScopes, dataClass: "private" }];
|
|
497
|
-
if (pack === "crm") return [{ id: "record.changed", title: "Record changed", requiredScopes, dataClass: "private" }];
|
|
498
|
-
if (pack === "support") return [{ id: "ticket.changed", title: "Ticket changed", requiredScopes, dataClass: "private" }];
|
|
499
|
-
if (pack === "commerce") return [{ id: "order.changed", title: "Order changed", requiredScopes, dataClass: "sensitive" }];
|
|
500
|
-
if (pack === "finance") return [{ id: "transaction.changed", title: "Transaction changed", requiredScopes, dataClass: "sensitive" }];
|
|
501
|
-
if (pack === "workflow" || pack === "webhook") return [{ id: "event.received", title: "Event received", requiredScopes, dataClass: "internal" }];
|
|
496
|
+
const requiredScopes2 = readScope ? [readScope] : [];
|
|
497
|
+
if (pack === "email") return [{ id: "message.received", title: "Message received", requiredScopes: requiredScopes2, dataClass: "private" }];
|
|
498
|
+
if (pack === "calendar") return [{ id: "event.changed", title: "Event changed", requiredScopes: requiredScopes2, dataClass: "private" }];
|
|
499
|
+
if (pack === "chat") return [{ id: "message.posted", title: "Message posted", requiredScopes: requiredScopes2, dataClass: "private" }];
|
|
500
|
+
if (pack === "crm") return [{ id: "record.changed", title: "Record changed", requiredScopes: requiredScopes2, dataClass: "private" }];
|
|
501
|
+
if (pack === "support") return [{ id: "ticket.changed", title: "Ticket changed", requiredScopes: requiredScopes2, dataClass: "private" }];
|
|
502
|
+
if (pack === "commerce") return [{ id: "order.changed", title: "Order changed", requiredScopes: requiredScopes2, dataClass: "sensitive" }];
|
|
503
|
+
if (pack === "finance") return [{ id: "transaction.changed", title: "Transaction changed", requiredScopes: requiredScopes2, dataClass: "sensitive" }];
|
|
504
|
+
if (pack === "workflow" || pack === "webhook") return [{ id: "event.received", title: "Event received", requiredScopes: requiredScopes2, dataClass: "internal" }];
|
|
502
505
|
return void 0;
|
|
503
506
|
}
|
|
504
507
|
function scopesFor(id, pack) {
|
|
@@ -1175,6 +1178,8 @@ function inferIntegrationSupportTier(connector) {
|
|
|
1175
1178
|
if (metadata.source === "first-party-adapter" || connector.providerId === "first-party") return "firstPartyExecutable";
|
|
1176
1179
|
if (metadata.source === "gateway-catalog" && metadata.executable === true) return "gatewayExecutable";
|
|
1177
1180
|
if (metadata.source === "integration-spec") return "setupReady";
|
|
1181
|
+
if (metadata.source === "coverage-catalog" || metadata.source === "activepieces-community" || metadata.catalogOnly === true) return "catalogOnly";
|
|
1182
|
+
if (connector.actions.length > 0) return "gatewayExecutable";
|
|
1178
1183
|
return "catalogOnly";
|
|
1179
1184
|
}
|
|
1180
1185
|
function registryEntry(canonicalId, candidates, precedence, aliases) {
|
|
@@ -1221,7 +1226,7 @@ function registryEntry(canonicalId, candidates, precedence, aliases) {
|
|
|
1221
1226
|
sources,
|
|
1222
1227
|
conflicts,
|
|
1223
1228
|
toolBindable: actions.length > 0,
|
|
1224
|
-
catalogOnlyActionCount: ordered.filter((candidate) => candidate.supportTier === "catalogOnly").reduce((sum, candidate) => sum + candidate.connector
|
|
1229
|
+
catalogOnlyActionCount: ordered.filter((candidate) => candidate.supportTier === "catalogOnly").reduce((sum, candidate) => sum + catalogActionCount(candidate.connector), 0)
|
|
1225
1230
|
}
|
|
1226
1231
|
}
|
|
1227
1232
|
}
|
|
@@ -1252,6 +1257,10 @@ function toolBindableCandidates(candidates) {
|
|
|
1252
1257
|
const bindable = candidates.filter((candidate) => candidate.supportTier !== "catalogOnly");
|
|
1253
1258
|
return bindable.length > 0 ? bindable : [];
|
|
1254
1259
|
}
|
|
1260
|
+
function catalogActionCount(connector) {
|
|
1261
|
+
const value = connector.metadata?.catalogActionCount;
|
|
1262
|
+
return typeof value === "number" ? value : connector.actions.length;
|
|
1263
|
+
}
|
|
1255
1264
|
function conflictDiagnostics(candidates) {
|
|
1256
1265
|
return [
|
|
1257
1266
|
conflictFor("auth", candidates.map((candidate) => ({
|
|
@@ -5244,6 +5253,295 @@ function unique4(values) {
|
|
|
5244
5253
|
return [...new Set(values)];
|
|
5245
5254
|
}
|
|
5246
5255
|
|
|
5256
|
+
// src/runtime.ts
|
|
5257
|
+
var InMemoryIntegrationGrantStore = class {
|
|
5258
|
+
grants = /* @__PURE__ */ new Map();
|
|
5259
|
+
get(grantId) {
|
|
5260
|
+
return this.grants.get(grantId);
|
|
5261
|
+
}
|
|
5262
|
+
put(grant) {
|
|
5263
|
+
this.grants.set(grant.id, grant);
|
|
5264
|
+
}
|
|
5265
|
+
listByManifest(manifestId, grantee) {
|
|
5266
|
+
return [...this.grants.values()].filter(
|
|
5267
|
+
(grant) => grant.manifestId === manifestId && (!grantee || sameActor(grant.grantee, grantee))
|
|
5268
|
+
);
|
|
5269
|
+
}
|
|
5270
|
+
listByGrantee(grantee) {
|
|
5271
|
+
return [...this.grants.values()].filter((grant) => sameActor(grant.grantee, grantee));
|
|
5272
|
+
}
|
|
5273
|
+
delete(grantId) {
|
|
5274
|
+
this.grants.delete(grantId);
|
|
5275
|
+
}
|
|
5276
|
+
};
|
|
5277
|
+
var IntegrationRuntime = class {
|
|
5278
|
+
hub;
|
|
5279
|
+
grants;
|
|
5280
|
+
now;
|
|
5281
|
+
constructor(options) {
|
|
5282
|
+
this.hub = options.hub;
|
|
5283
|
+
this.grants = options.grants ?? new InMemoryIntegrationGrantStore();
|
|
5284
|
+
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
5285
|
+
}
|
|
5286
|
+
async registry() {
|
|
5287
|
+
return this.hub.listRegistry();
|
|
5288
|
+
}
|
|
5289
|
+
async resolveManifest(manifest, owner) {
|
|
5290
|
+
const registry = await this.registry();
|
|
5291
|
+
const connections = await this.hub.listConnections(owner);
|
|
5292
|
+
const resolutions = manifest.requirements.map(
|
|
5293
|
+
(requirement) => resolveRequirement(requirement, owner, registry, connections)
|
|
5294
|
+
);
|
|
5295
|
+
return {
|
|
5296
|
+
manifest,
|
|
5297
|
+
owner,
|
|
5298
|
+
ready: resolutions.filter((resolution) => resolution.status === "ready"),
|
|
5299
|
+
missing: resolutions.filter((resolution) => resolution.status !== "ready" && !resolution.requirement.optional),
|
|
5300
|
+
optionalMissing: resolutions.filter((resolution) => resolution.status !== "ready" && resolution.requirement.optional === true)
|
|
5301
|
+
};
|
|
5302
|
+
}
|
|
5303
|
+
async createGrants(input) {
|
|
5304
|
+
const resolution = await this.resolveManifest(input.manifest, input.owner);
|
|
5305
|
+
if (resolution.missing.length > 0) {
|
|
5306
|
+
throw new Error(`Cannot create integration grants; missing requirements: ${resolution.missing.map((r) => r.requirement.id).join(", ")}`);
|
|
5307
|
+
}
|
|
5308
|
+
const now = this.now().toISOString();
|
|
5309
|
+
const grants = resolution.ready.map((ready) => ({
|
|
5310
|
+
id: `grant_${input.manifest.id}_${ready.requirement.id}_${ready.connection.id}`,
|
|
5311
|
+
manifestId: input.manifest.id,
|
|
5312
|
+
requirementId: ready.requirement.id,
|
|
5313
|
+
owner: input.owner,
|
|
5314
|
+
grantee: input.grantee,
|
|
5315
|
+
connectionId: ready.connection.id,
|
|
5316
|
+
connectorId: ready.connector.id,
|
|
5317
|
+
scopes: requiredScopes(ready.requirement, ready.connector),
|
|
5318
|
+
allowedActions: requiredActions(ready.requirement, ready.connector),
|
|
5319
|
+
allowedTriggers: requiredTriggers(ready.requirement, ready.connector),
|
|
5320
|
+
status: "active",
|
|
5321
|
+
createdAt: now,
|
|
5322
|
+
updatedAt: now,
|
|
5323
|
+
metadata: input.metadata
|
|
5324
|
+
}));
|
|
5325
|
+
for (const grant of grants) await this.grants.put(grant);
|
|
5326
|
+
return grants;
|
|
5327
|
+
}
|
|
5328
|
+
async buildSandboxBundle(input) {
|
|
5329
|
+
const grants = (await this.grants.listByManifest(input.manifestId, input.grantee)).filter((grant) => grant.status === "active");
|
|
5330
|
+
const registry = await this.registry();
|
|
5331
|
+
const bindings = [];
|
|
5332
|
+
const connectors = [];
|
|
5333
|
+
let expiresAt = "";
|
|
5334
|
+
for (const grant of grants) {
|
|
5335
|
+
const entry = registry.byId.get(grant.connectorId);
|
|
5336
|
+
if (!entry) continue;
|
|
5337
|
+
const connector = {
|
|
5338
|
+
...entry.connector,
|
|
5339
|
+
actions: entry.connector.actions.filter((action) => grant.allowedActions.includes(action.id)),
|
|
5340
|
+
triggers: entry.connector.triggers?.filter((trigger) => grant.allowedTriggers.includes(trigger.id)),
|
|
5341
|
+
scopes: entry.connector.scopes.filter((scope) => grant.scopes.includes(scope))
|
|
5342
|
+
};
|
|
5343
|
+
const capability = await this.hub.issueCapability({
|
|
5344
|
+
subject: input.subject,
|
|
5345
|
+
connectionId: grant.connectionId,
|
|
5346
|
+
scopes: grant.scopes,
|
|
5347
|
+
allowedActions: grant.allowedActions,
|
|
5348
|
+
ttlMs: input.ttlMs,
|
|
5349
|
+
metadata: {
|
|
5350
|
+
manifestId: grant.manifestId,
|
|
5351
|
+
grantId: grant.id,
|
|
5352
|
+
requirementId: grant.requirementId
|
|
5353
|
+
}
|
|
5354
|
+
});
|
|
5355
|
+
bindings.push({
|
|
5356
|
+
requirementId: grant.requirementId,
|
|
5357
|
+
connectorId: grant.connectorId,
|
|
5358
|
+
connectionId: grant.connectionId,
|
|
5359
|
+
grantId: grant.id,
|
|
5360
|
+
scopes: grant.scopes,
|
|
5361
|
+
allowedActions: grant.allowedActions,
|
|
5362
|
+
allowedTriggers: grant.allowedTriggers,
|
|
5363
|
+
capability
|
|
5364
|
+
});
|
|
5365
|
+
connectors.push(connector);
|
|
5366
|
+
expiresAt = capability.capability.expiresAt;
|
|
5367
|
+
}
|
|
5368
|
+
return {
|
|
5369
|
+
manifestId: input.manifestId,
|
|
5370
|
+
subject: input.subject,
|
|
5371
|
+
capabilities: bindings,
|
|
5372
|
+
connectors,
|
|
5373
|
+
tools: buildIntegrationToolCatalog(connectors),
|
|
5374
|
+
expiresAt
|
|
5375
|
+
};
|
|
5376
|
+
}
|
|
5377
|
+
};
|
|
5378
|
+
function createIntegrationRuntime(options) {
|
|
5379
|
+
return new IntegrationRuntime(options);
|
|
5380
|
+
}
|
|
5381
|
+
function resolveRequirement(requirement, owner, registry, connections) {
|
|
5382
|
+
const entry = registry.byId.get(requirement.connectorId);
|
|
5383
|
+
if (!entry) {
|
|
5384
|
+
return missing(requirement, "unknown_connector", `Unknown connector ${requirement.connectorId}.`);
|
|
5385
|
+
}
|
|
5386
|
+
const connector = entry.connector;
|
|
5387
|
+
if (connector.actions.length === 0 && (connector.triggers?.length ?? 0) === 0) {
|
|
5388
|
+
return missing(requirement, "not_executable", `${connector.title} is catalog-only and cannot be invoked yet.`, connector, entry);
|
|
5389
|
+
}
|
|
5390
|
+
const scopes = requiredScopes(requirement, connector);
|
|
5391
|
+
const actions = requiredActions(requirement, connector);
|
|
5392
|
+
const triggers = requiredTriggers(requirement, connector);
|
|
5393
|
+
const connection = connections.find(
|
|
5394
|
+
(candidate) => sameActor(candidate.owner, owner) && candidate.status === "active" && (candidate.connectorId === connector.id || entry.aliases.includes(candidate.connectorId)) && scopes.every((scope) => candidate.grantedScopes.includes(scope))
|
|
5395
|
+
);
|
|
5396
|
+
if (!connection) {
|
|
5397
|
+
return {
|
|
5398
|
+
requirement,
|
|
5399
|
+
status: "missing_connection",
|
|
5400
|
+
connector,
|
|
5401
|
+
registryEntry: entry,
|
|
5402
|
+
missingScopes: scopes,
|
|
5403
|
+
missingActions: actions,
|
|
5404
|
+
missingTriggers: triggers,
|
|
5405
|
+
message: `${connector.title} needs an active user connection with the required scopes.`
|
|
5406
|
+
};
|
|
5407
|
+
}
|
|
5408
|
+
return {
|
|
5409
|
+
requirement,
|
|
5410
|
+
status: "ready",
|
|
5411
|
+
connector,
|
|
5412
|
+
registryEntry: entry,
|
|
5413
|
+
connection,
|
|
5414
|
+
missingScopes: [],
|
|
5415
|
+
missingActions: [],
|
|
5416
|
+
missingTriggers: [],
|
|
5417
|
+
message: `${connector.title} is ready.`
|
|
5418
|
+
};
|
|
5419
|
+
}
|
|
5420
|
+
function missing(requirement, status, message, connector, registryEntry2) {
|
|
5421
|
+
return {
|
|
5422
|
+
requirement,
|
|
5423
|
+
status,
|
|
5424
|
+
connector,
|
|
5425
|
+
registryEntry: registryEntry2,
|
|
5426
|
+
missingScopes: [],
|
|
5427
|
+
missingActions: [],
|
|
5428
|
+
missingTriggers: [],
|
|
5429
|
+
message
|
|
5430
|
+
};
|
|
5431
|
+
}
|
|
5432
|
+
function requiredActions(requirement, connector) {
|
|
5433
|
+
if (requirement.mode === "trigger") return [];
|
|
5434
|
+
if (requirement.requiredActions?.length) return unique5(requirement.requiredActions);
|
|
5435
|
+
const actions = connector.actions.filter((action) => {
|
|
5436
|
+
if (requirement.mode === "read") return action.risk === "read";
|
|
5437
|
+
if (requirement.mode === "write") return action.risk !== "read";
|
|
5438
|
+
return false;
|
|
5439
|
+
});
|
|
5440
|
+
return unique5(actions.map((action) => action.id));
|
|
5441
|
+
}
|
|
5442
|
+
function requiredTriggers(requirement, connector) {
|
|
5443
|
+
if (requirement.requiredTriggers?.length) return unique5(requirement.requiredTriggers);
|
|
5444
|
+
if (requirement.mode !== "trigger") return [];
|
|
5445
|
+
return unique5((connector.triggers ?? []).map((trigger) => trigger.id));
|
|
5446
|
+
}
|
|
5447
|
+
function requiredScopes(requirement, connector) {
|
|
5448
|
+
if (requirement.requiredScopes?.length) return unique5(requirement.requiredScopes);
|
|
5449
|
+
const actionIds = new Set(requiredActions(requirement, connector));
|
|
5450
|
+
const triggerIds = new Set(requiredTriggers(requirement, connector));
|
|
5451
|
+
return unique5([
|
|
5452
|
+
...connector.actions.filter((action) => actionIds.has(action.id)).flatMap((action) => action.requiredScopes),
|
|
5453
|
+
...(connector.triggers ?? []).filter((trigger) => triggerIds.has(trigger.id)).flatMap((trigger) => trigger.requiredScopes)
|
|
5454
|
+
]);
|
|
5455
|
+
}
|
|
5456
|
+
function sameActor(a, b) {
|
|
5457
|
+
return a.type === b.type && a.id === b.id;
|
|
5458
|
+
}
|
|
5459
|
+
function unique5(values) {
|
|
5460
|
+
return [...new Set(values)];
|
|
5461
|
+
}
|
|
5462
|
+
|
|
5463
|
+
// src/workflow.ts
|
|
5464
|
+
var InMemoryIntegrationWorkflowStore = class {
|
|
5465
|
+
workflows = /* @__PURE__ */ new Map();
|
|
5466
|
+
put(workflow) {
|
|
5467
|
+
this.workflows.set(workflow.id, workflow);
|
|
5468
|
+
}
|
|
5469
|
+
get(id) {
|
|
5470
|
+
return this.workflows.get(id);
|
|
5471
|
+
}
|
|
5472
|
+
list() {
|
|
5473
|
+
return [...this.workflows.values()];
|
|
5474
|
+
}
|
|
5475
|
+
listByWorkflow(workflowId) {
|
|
5476
|
+
return [...this.workflows.values()].filter((workflow) => workflow.workflowId === workflowId);
|
|
5477
|
+
}
|
|
5478
|
+
listByOwner(owner) {
|
|
5479
|
+
return [...this.workflows.values()].filter((workflow) => sameActor2(workflow.owner, owner));
|
|
5480
|
+
}
|
|
5481
|
+
};
|
|
5482
|
+
var IntegrationWorkflowRuntime = class {
|
|
5483
|
+
runtime;
|
|
5484
|
+
hub;
|
|
5485
|
+
grants;
|
|
5486
|
+
store;
|
|
5487
|
+
now;
|
|
5488
|
+
constructor(options) {
|
|
5489
|
+
this.runtime = options.runtime;
|
|
5490
|
+
this.hub = options.hub;
|
|
5491
|
+
this.grants = options.grants;
|
|
5492
|
+
this.store = options.store ?? new InMemoryIntegrationWorkflowStore();
|
|
5493
|
+
this.now = options.now ?? (() => /* @__PURE__ */ new Date());
|
|
5494
|
+
}
|
|
5495
|
+
async install(input) {
|
|
5496
|
+
const grants = await this.runtime.createGrants({
|
|
5497
|
+
manifest: input.workflow.manifest,
|
|
5498
|
+
owner: input.owner,
|
|
5499
|
+
grantee: input.grantee,
|
|
5500
|
+
metadata: { workflowId: input.workflow.id }
|
|
5501
|
+
});
|
|
5502
|
+
const triggerGrant = findTriggerGrant(grants, input.workflow.trigger.requirementId, input.workflow.trigger.triggerId);
|
|
5503
|
+
const subscription = await this.hub.subscribeTrigger(
|
|
5504
|
+
triggerGrant.connectionId,
|
|
5505
|
+
input.workflow.trigger.triggerId,
|
|
5506
|
+
input.workflow.trigger.targetUrl
|
|
5507
|
+
);
|
|
5508
|
+
const installed = {
|
|
5509
|
+
id: `workflow_${input.workflow.id}_${triggerGrant.id}`,
|
|
5510
|
+
workflowId: input.workflow.id,
|
|
5511
|
+
manifestId: input.workflow.manifest.id,
|
|
5512
|
+
owner: input.owner,
|
|
5513
|
+
grantee: input.grantee,
|
|
5514
|
+
triggerGrantId: triggerGrant.id,
|
|
5515
|
+
subscription,
|
|
5516
|
+
status: "active",
|
|
5517
|
+
createdAt: this.now().toISOString(),
|
|
5518
|
+
metadata: input.workflow.metadata
|
|
5519
|
+
};
|
|
5520
|
+
await this.store.put(installed);
|
|
5521
|
+
return installed;
|
|
5522
|
+
}
|
|
5523
|
+
async dispatchEvent(event, handler) {
|
|
5524
|
+
const workflows = (await this.store.list()).filter(
|
|
5525
|
+
(workflow) => workflow.status === "active" && workflow.subscription.connectionId === event.connectionId && workflow.subscription.trigger === event.trigger
|
|
5526
|
+
);
|
|
5527
|
+
await handler({ event, workflows });
|
|
5528
|
+
return { matched: workflows };
|
|
5529
|
+
}
|
|
5530
|
+
};
|
|
5531
|
+
function createIntegrationWorkflowRuntime(options) {
|
|
5532
|
+
return new IntegrationWorkflowRuntime(options);
|
|
5533
|
+
}
|
|
5534
|
+
function findTriggerGrant(grants, requirementId, triggerId) {
|
|
5535
|
+
const grant = grants.find(
|
|
5536
|
+
(candidate) => candidate.requirementId === requirementId && candidate.allowedTriggers.includes(triggerId)
|
|
5537
|
+
);
|
|
5538
|
+
if (!grant) throw new Error(`Missing trigger grant ${requirementId}/${triggerId}.`);
|
|
5539
|
+
return grant;
|
|
5540
|
+
}
|
|
5541
|
+
function sameActor2(a, b) {
|
|
5542
|
+
return a.type === b.type && a.id === b.id;
|
|
5543
|
+
}
|
|
5544
|
+
|
|
5247
5545
|
// src/specs/types.ts
|
|
5248
5546
|
function specAuthToConnectorAuth(auth) {
|
|
5249
5547
|
if (auth.mode === "api_key") return "api_key";
|
|
@@ -5433,6 +5731,9 @@ var IntegrationHub = class {
|
|
|
5433
5731
|
await this.store.put(connection);
|
|
5434
5732
|
return connection;
|
|
5435
5733
|
}
|
|
5734
|
+
async listConnections(owner) {
|
|
5735
|
+
return this.store.listByOwner(owner);
|
|
5736
|
+
}
|
|
5436
5737
|
async issueCapability(request) {
|
|
5437
5738
|
const connection = await this.requireConnection(request.connectionId);
|
|
5438
5739
|
this.assertConnectionActive(connection);
|
|
@@ -5442,8 +5743,8 @@ var IntegrationHub = class {
|
|
|
5442
5743
|
id: `cap_${randomUUID2()}`,
|
|
5443
5744
|
subject: request.subject,
|
|
5444
5745
|
connectionId: request.connectionId,
|
|
5445
|
-
scopes:
|
|
5446
|
-
allowedActions:
|
|
5746
|
+
scopes: unique6(request.scopes),
|
|
5747
|
+
allowedActions: unique6(request.allowedActions),
|
|
5447
5748
|
issuedAt: now.toISOString(),
|
|
5448
5749
|
expiresAt: new Date(now.getTime() + request.ttlMs).toISOString(),
|
|
5449
5750
|
metadata: request.metadata
|
|
@@ -5671,9 +5972,9 @@ async function postJson(fetcher, url, body, bearer) {
|
|
|
5671
5972
|
if (!response.ok) throw new IntegrationError(`Integration provider returned HTTP ${response.status}.`, "provider_not_found");
|
|
5672
5973
|
return response.json();
|
|
5673
5974
|
}
|
|
5674
|
-
function assertScopes(connection,
|
|
5675
|
-
const
|
|
5676
|
-
if (
|
|
5975
|
+
function assertScopes(connection, requiredScopes2) {
|
|
5976
|
+
const missing2 = requiredScopes2.filter((scope) => !connection.grantedScopes.includes(scope));
|
|
5977
|
+
if (missing2.length > 0) throw new IntegrationError(`Missing integration scopes: ${missing2.join(", ")}`, "scope_denied");
|
|
5677
5978
|
}
|
|
5678
5979
|
function hmac(payload, secret) {
|
|
5679
5980
|
return createHmac3("sha256", secret).update(payload).digest("base64url");
|
|
@@ -5689,7 +5990,7 @@ function base64UrlEncode(value) {
|
|
|
5689
5990
|
function base64UrlDecode(value) {
|
|
5690
5991
|
return Buffer.from(value, "base64url").toString("utf8");
|
|
5691
5992
|
}
|
|
5692
|
-
function
|
|
5993
|
+
function unique6(values) {
|
|
5693
5994
|
return [...new Set(values)];
|
|
5694
5995
|
}
|
|
5695
5996
|
export {
|
|
@@ -5698,9 +5999,13 @@ export {
|
|
|
5698
5999
|
DEFAULT_SIGNATURE_TOLERANCE_SECONDS,
|
|
5699
6000
|
INTEGRATION_FAMILIES,
|
|
5700
6001
|
InMemoryConnectionStore,
|
|
6002
|
+
InMemoryIntegrationGrantStore,
|
|
6003
|
+
InMemoryIntegrationWorkflowStore,
|
|
5701
6004
|
InMemoryOAuthFlowStore,
|
|
5702
6005
|
IntegrationError,
|
|
5703
6006
|
IntegrationHub,
|
|
6007
|
+
IntegrationRuntime,
|
|
6008
|
+
IntegrationWorkflowRuntime,
|
|
5704
6009
|
ResourceContention,
|
|
5705
6010
|
StaticIntegrationPolicyEngine,
|
|
5706
6011
|
_resetPendingFlowsForTests,
|
|
@@ -5723,6 +6028,8 @@ export {
|
|
|
5723
6028
|
createDefaultIntegrationPolicyEngine,
|
|
5724
6029
|
createGatewayCatalogProvider,
|
|
5725
6030
|
createHttpIntegrationProvider,
|
|
6031
|
+
createIntegrationRuntime,
|
|
6032
|
+
createIntegrationWorkflowRuntime,
|
|
5726
6033
|
createMockIntegrationProvider,
|
|
5727
6034
|
declarativeRestConnector,
|
|
5728
6035
|
exchangeAuthorizationCode,
|