@tangle-network/agent-integrations 0.19.0 → 0.21.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/dist/index.js CHANGED
@@ -18,7 +18,7 @@ import {
18
18
  validateCredentialFormat,
19
19
  validateCredentialSet,
20
20
  validateIntegrationSpec
21
- } from "./chunk-DIJ3I66K.js";
21
+ } from "./chunk-L6WBPDUP.js";
22
22
 
23
23
  // src/index.ts
24
24
  import { createHmac as createHmac4, randomUUID as randomUUID4, timingSafeEqual as timingSafeEqual3 } from "crypto";
@@ -250,6 +250,7 @@ var DEFAULT_SOURCE_PRECEDENCE = {
250
250
  "first-party": 500,
251
251
  spec: 400,
252
252
  gateway: 300,
253
+ "tangle-catalog": 100,
253
254
  activepieces: 100,
254
255
  coverage: 50
255
256
  };
@@ -262,7 +263,7 @@ var SUPPORT_RANK = {
262
263
  };
263
264
  function buildDefaultIntegrationRegistry(options = {}) {
264
265
  const includeSpecs = options.includeSpecs ?? true;
265
- const includeActivepieces = options.includeActivepieces ?? true;
266
+ const includeTangleCatalog = options.includeTangleCatalog ?? options.includeActivepieces ?? true;
266
267
  const sources = [];
267
268
  if (includeSpecs) {
268
269
  sources.push({
@@ -270,10 +271,27 @@ function buildDefaultIntegrationRegistry(options = {}) {
270
271
  connectors: listIntegrationSpecs().map((spec) => integrationSpecToConnector(spec, "spec"))
271
272
  });
272
273
  }
273
- if (includeActivepieces) {
274
+ if (includeTangleCatalog) {
274
275
  sources.push({
275
- id: "activepieces",
276
- connectors: buildActivepiecesConnectors()
276
+ id: "tangle-catalog",
277
+ connectors: buildActivepiecesConnectors({ providerId: "tangle-catalog" }).map((connector) => ({
278
+ ...connector,
279
+ providerId: "tangle-catalog",
280
+ metadata: {
281
+ source: "tangle-integrations-catalog",
282
+ providerId: "tangle-catalog",
283
+ executable: connector.metadata?.executable,
284
+ runtime: "tangle-catalog-runtime",
285
+ catalogOnly: connector.metadata?.catalogOnly,
286
+ supportTier: connector.metadata?.supportTier,
287
+ catalogActionCount: connector.metadata?.catalogActionCount,
288
+ catalogTriggerCount: connector.metadata?.catalogTriggerCount,
289
+ license: connector.metadata?.license,
290
+ version: connector.metadata?.version,
291
+ domains: Array.isArray(connector.metadata?.domains) ? connector.metadata.domains.filter((domain) => typeof domain === "string" && !domain.toLowerCase().includes("activepieces")) : void 0,
292
+ ...connector.metadata?.overridden ? { overridden: true } : {}
293
+ }
294
+ }))
277
295
  });
278
296
  }
279
297
  return composeIntegrationRegistry(sources);
@@ -341,7 +359,7 @@ function inferIntegrationSupportTier(connector) {
341
359
  if (metadata.source === "first-party-adapter" || connector.providerId === "first-party") return "firstPartyExecutable";
342
360
  if (metadata.source === "gateway-catalog" && metadata.executable === true) return "gatewayExecutable";
343
361
  if (metadata.source === "integration-spec") return "setupReady";
344
- if (metadata.source === "coverage-catalog" || metadata.source === "activepieces-community" || metadata.catalogOnly === true) return "catalogOnly";
362
+ if (metadata.source === "coverage-catalog" || metadata.source === "activepieces-community" || metadata.source === "tangle-integrations-catalog" || metadata.catalogOnly === true) return "catalogOnly";
345
363
  if (connector.actions.length > 0) return "gatewayExecutable";
346
364
  return "catalogOnly";
347
365
  }
@@ -2139,10 +2157,11 @@ async function exchangeAuthorizationCode(input) {
2139
2157
  redirect_uri: input.redirectUri,
2140
2158
  code_verifier: input.codeVerifier
2141
2159
  });
2142
- const res = await fetch(input.tokenUrl, {
2160
+ const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
2143
2161
  method: "POST",
2144
2162
  headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" },
2145
- body
2163
+ body,
2164
+ signal: input.signal
2146
2165
  });
2147
2166
  if (!res.ok) {
2148
2167
  const text = await res.text().catch(() => "");
@@ -2164,10 +2183,11 @@ async function refreshAccessToken(input) {
2164
2183
  client_secret: input.clientSecret,
2165
2184
  refresh_token: input.refreshToken
2166
2185
  });
2167
- const res = await fetch(input.tokenUrl, {
2186
+ const res = await (input.fetchImpl ?? fetch)(input.tokenUrl, {
2168
2187
  method: "POST",
2169
2188
  headers: { "content-type": "application/x-www-form-urlencoded", accept: "application/json" },
2170
- body
2189
+ body,
2190
+ signal: input.signal
2171
2191
  });
2172
2192
  if (!res.ok) {
2173
2193
  const text = await res.text().catch(() => "");
@@ -5890,13 +5910,63 @@ function verifyActivepiecesRuntimeSignature(serializedBody, signature, secret) {
5890
5910
  return left.length === right.length && timingSafeEqual2(left, right);
5891
5911
  }
5892
5912
  function createTangleCatalogHttpExecutor(options) {
5893
- return createActivepiecesHttpExecutor({
5894
- ...options,
5895
- path: options.path ?? "/v1/integration-catalog/actions/invoke",
5896
- signatureHeader: options.signatureHeader ?? TANGLE_CATALOG_RUNTIME_SIGNATURE_HEADER
5897
- });
5913
+ const endpoint = options.endpoint.replace(/\/$/, "");
5914
+ const path = options.path ?? "/v1/integration-catalog/actions/invoke";
5915
+ const normalizedPath = path.startsWith("/") ? path : `/${path}`;
5916
+ const signatureHeader = options.signatureHeader ?? TANGLE_CATALOG_RUNTIME_SIGNATURE_HEADER;
5917
+ const fetchImpl = options.fetchImpl ?? fetch;
5918
+ const requestId = options.requestId ?? (() => `tcat_${randomUUID3()}`);
5919
+ return async (invocation) => {
5920
+ const body = buildTangleCatalogRuntimeRequest(invocation, requestId());
5921
+ const serialized = JSON.stringify(body);
5922
+ const response = await fetchImpl(`${endpoint}${normalizedPath}`, {
5923
+ method: "POST",
5924
+ headers: {
5925
+ "content-type": "application/json",
5926
+ ...options.headers,
5927
+ ...options.secret ? { [signatureHeader]: signTangleCatalogRuntimeRequest(serialized, options.secret) } : {}
5928
+ },
5929
+ body: serialized,
5930
+ signal: AbortSignal.timeout(options.timeoutMs ?? 3e4)
5931
+ });
5932
+ const parsed = await response.json().catch(() => void 0);
5933
+ if (!response.ok) {
5934
+ return parsed ?? {
5935
+ ok: false,
5936
+ action: invocation.request.action,
5937
+ output: { message: `Tangle catalog runtime returned HTTP ${response.status}.` }
5938
+ };
5939
+ }
5940
+ return parsed ?? {
5941
+ ok: false,
5942
+ action: invocation.request.action,
5943
+ output: { message: "Tangle catalog runtime returned an empty response." }
5944
+ };
5945
+ };
5946
+ }
5947
+ function buildTangleCatalogRuntimeRequest(invocation, requestId = `tcat_${randomUUID3()}`) {
5948
+ return {
5949
+ version: 1,
5950
+ requestId,
5951
+ providerId: invocation.connection.providerId,
5952
+ connection: invocation.connection,
5953
+ connector: {
5954
+ id: invocation.connector.id,
5955
+ title: invocation.connector.title,
5956
+ auth: invocation.connector.auth,
5957
+ scopes: invocation.connector.scopes,
5958
+ metadata: invocation.connector.metadata
5959
+ },
5960
+ piece: invocation.piece,
5961
+ action: {
5962
+ id: invocation.request.action,
5963
+ input: invocation.request.input,
5964
+ idempotencyKey: invocation.request.idempotencyKey,
5965
+ dryRun: invocation.request.dryRun,
5966
+ metadata: invocation.request.metadata
5967
+ }
5968
+ };
5898
5969
  }
5899
- var buildTangleCatalogRuntimeRequest = buildActivepiecesRuntimeRequest;
5900
5970
  var signTangleCatalogRuntimeRequest = signActivepiecesRuntimeRequest;
5901
5971
  var verifyTangleCatalogRuntimeSignature = verifyActivepiecesRuntimeSignature;
5902
5972
 
@@ -6031,9 +6101,53 @@ async function checkActivepiecesPublicCatalog(input) {
6031
6101
  }
6032
6102
 
6033
6103
  // src/tangle-catalog.ts
6034
- var listTangleIntegrationCatalogEntries = listActivepiecesCatalogEntries;
6035
- var buildTangleIntegrationCatalogConnectors = buildActivepiecesConnectors;
6036
- var createTangleCatalogExecutorProvider = createActivepiecesExecutorProvider;
6104
+ var TANGLE_INTEGRATIONS_CATALOG_PROVIDER_ID = "tangle-catalog";
6105
+ var TANGLE_INTEGRATIONS_CATALOG_SOURCE = "tangle-integrations-catalog";
6106
+ function listTangleIntegrationCatalogEntries() {
6107
+ return listActivepiecesCatalogEntries().map((entry) => sanitizeEntry(entry));
6108
+ }
6109
+ function buildTangleIntegrationCatalogConnectors(options = {}) {
6110
+ const providerId = options.providerId ?? TANGLE_INTEGRATIONS_CATALOG_PROVIDER_ID;
6111
+ return buildActivepiecesConnectors({
6112
+ ...options,
6113
+ providerId
6114
+ }).map((connector) => sanitizeConnector(connector, providerId));
6115
+ }
6116
+ function createTangleCatalogExecutorProvider(options) {
6117
+ const providerId = options.id ?? TANGLE_INTEGRATIONS_CATALOG_PROVIDER_ID;
6118
+ const connectors = options.connectors ?? buildTangleIntegrationCatalogConnectors({
6119
+ providerId,
6120
+ includeCatalogActions: true,
6121
+ executable: true
6122
+ });
6123
+ const byEntry = new Map(listActivepiecesCatalogEntries().map((entry) => [entry.id, entry]));
6124
+ return createCatalogExecutorProvider({
6125
+ id: providerId,
6126
+ kind: "tangle_catalog",
6127
+ connectors,
6128
+ startAuth: options.startAuth,
6129
+ completeAuth: options.completeAuth,
6130
+ executeAction: async ({ connection, request, connector, action }) => {
6131
+ const importedEntry = byEntry.get(connector.id);
6132
+ if (!importedEntry) {
6133
+ throw new IntegrationError(`Tangle catalog entry ${connector.id} not found.`, "connector_not_found");
6134
+ }
6135
+ const catalogAction = importedEntry.actions.find((candidate) => candidate.id === action.id);
6136
+ return options.executeAction({
6137
+ connection,
6138
+ request,
6139
+ connector,
6140
+ catalogEntry: sanitizeEntry(importedEntry),
6141
+ piece: {
6142
+ id: importedEntry.id,
6143
+ version: importedEntry.version,
6144
+ actionId: action.id,
6145
+ upstreamActionName: catalogAction?.upstreamName
6146
+ }
6147
+ });
6148
+ }
6149
+ });
6150
+ }
6037
6151
  var extractExternalCatalogPublicCount = extractActivepiecesPublicPieceCount;
6038
6152
  async function auditTangleIntegrationCatalogFreshness(options = {}) {
6039
6153
  const result = await auditIntegrationCatalogFreshness(options);
@@ -6063,6 +6177,142 @@ async function auditTangleIntegrationCatalogFreshness(options = {}) {
6063
6177
  warnings: result.warnings.map((warning) => warning.replaceAll("Activepieces", "Tangle Integrations Catalog"))
6064
6178
  };
6065
6179
  }
6180
+ function sanitizeEntry(entry) {
6181
+ return {
6182
+ id: entry.id,
6183
+ title: entry.title,
6184
+ description: entry.description,
6185
+ category: entry.category,
6186
+ auth: entry.auth,
6187
+ domains: entry.domains.filter((domain) => !domain.toLowerCase().includes("activepieces")),
6188
+ actions: entry.actions.map((action) => ({
6189
+ id: action.id,
6190
+ title: action.title,
6191
+ risk: action.risk
6192
+ })),
6193
+ triggers: entry.triggers.map((trigger2) => ({
6194
+ id: trigger2.id,
6195
+ title: trigger2.title
6196
+ }))
6197
+ };
6198
+ }
6199
+ function sanitizeConnector(connector, providerId) {
6200
+ const metadata = connector.metadata ?? {};
6201
+ return {
6202
+ ...connector,
6203
+ providerId,
6204
+ metadata: {
6205
+ source: TANGLE_INTEGRATIONS_CATALOG_SOURCE,
6206
+ providerId,
6207
+ executable: metadata.executable,
6208
+ runtime: "tangle-catalog-runtime",
6209
+ catalogOnly: metadata.catalogOnly,
6210
+ supportTier: metadata.supportTier,
6211
+ catalogActionCount: metadata.catalogActionCount,
6212
+ catalogTriggerCount: metadata.catalogTriggerCount,
6213
+ license: metadata.license,
6214
+ version: metadata.version,
6215
+ domains: Array.isArray(metadata.domains) ? metadata.domains.filter((domain) => typeof domain === "string" && !domain.toLowerCase().includes("activepieces")) : void 0,
6216
+ ...metadata.overridden ? { overridden: true } : {}
6217
+ }
6218
+ };
6219
+ }
6220
+
6221
+ // src/tangle-catalog-runtime.ts
6222
+ function createTangleCatalogRuntimeHandler(options) {
6223
+ const connectors = options.connectors ?? buildTangleIntegrationCatalogConnectors({
6224
+ includeCatalogActions: true,
6225
+ executable: true
6226
+ });
6227
+ const byConnector = new Map(connectors.map((connector) => [connector.id, connector]));
6228
+ const requireSignature = options.requireSignature ?? Boolean(options.secret);
6229
+ const signatureHeader = options.signatureHeader ?? TANGLE_CATALOG_RUNTIME_SIGNATURE_HEADER;
6230
+ const maxBodyBytes = options.maxBodyBytes ?? 1e6;
6231
+ return async function handleTangleCatalogRuntimeRequest(input) {
6232
+ const serialized = serializeBody(input.body);
6233
+ if (Buffer.byteLength(serialized, "utf8") > maxBodyBytes) {
6234
+ return errorResponse(413, "unknown", "payload_too_large", "Tangle catalog runtime request is too large.");
6235
+ }
6236
+ if (requireSignature) {
6237
+ if (!options.secret) {
6238
+ return errorResponse(500, "unknown", "runtime_misconfigured", "Tangle catalog runtime secret is not configured.");
6239
+ }
6240
+ const signature = readHeader(input.headers, signatureHeader);
6241
+ if (!verifyTangleCatalogRuntimeSignature(serialized, signature, options.secret)) {
6242
+ return errorResponse(401, "unknown", "signature_invalid", "Tangle catalog runtime signature is invalid.");
6243
+ }
6244
+ }
6245
+ const parsed = parseRuntimeRequest(serialized);
6246
+ if (!parsed.ok) return parsed.response;
6247
+ const request = parsed.request;
6248
+ const connector = byConnector.get(request.connector.id);
6249
+ if (!connector) {
6250
+ return errorResponse(404, request.action.id, "connector_not_found", `Connector ${request.connector.id} is not in the Tangle catalog runtime.`);
6251
+ }
6252
+ if (request.connection.connectorId !== connector.id) {
6253
+ return errorResponse(400, request.action.id, "connector_mismatch", "Connection connectorId does not match runtime connector.");
6254
+ }
6255
+ if (request.connection.providerId !== connector.providerId) {
6256
+ return errorResponse(400, request.action.id, "provider_mismatch", "Connection providerId does not match runtime connector.");
6257
+ }
6258
+ const action = connector.actions.find((candidate) => candidate.id === request.action.id);
6259
+ if (!action) {
6260
+ return errorResponse(404, request.action.id, "action_not_found", `Action ${request.action.id} is not defined by connector ${connector.id}.`);
6261
+ }
6262
+ const result = await options.executeAction({
6263
+ request,
6264
+ connection: request.connection,
6265
+ connector,
6266
+ action
6267
+ });
6268
+ return {
6269
+ status: result.ok ? 200 : 502,
6270
+ headers: { "content-type": "application/json" },
6271
+ body: result
6272
+ };
6273
+ };
6274
+ }
6275
+ function serializeBody(body) {
6276
+ if (typeof body === "string") return body;
6277
+ if (body instanceof Uint8Array) return new TextDecoder().decode(body);
6278
+ return JSON.stringify(body);
6279
+ }
6280
+ function parseRuntimeRequest(serialized) {
6281
+ try {
6282
+ const request = JSON.parse(serialized);
6283
+ if (request.version !== 1) {
6284
+ return { ok: false, response: errorResponse(400, request.action?.id ?? "unknown", "version_invalid", "Unsupported Tangle catalog runtime request version.") };
6285
+ }
6286
+ if (!request.connection || !request.connector || !request.action?.id) {
6287
+ return { ok: false, response: errorResponse(400, request.action?.id ?? "unknown", "request_invalid", "Tangle catalog runtime request is missing required fields.") };
6288
+ }
6289
+ return { ok: true, request };
6290
+ } catch {
6291
+ return { ok: false, response: errorResponse(400, "unknown", "json_invalid", "Tangle catalog runtime request body is not valid JSON.") };
6292
+ }
6293
+ }
6294
+ function readHeader(headers, name) {
6295
+ if (!headers) return void 0;
6296
+ if (headers instanceof Headers) return headers.get(name) ?? void 0;
6297
+ const wanted = name.toLowerCase();
6298
+ for (const [key, value] of Object.entries(headers)) {
6299
+ if (key.toLowerCase() !== wanted) continue;
6300
+ if (Array.isArray(value)) return value[0];
6301
+ return value;
6302
+ }
6303
+ return void 0;
6304
+ }
6305
+ function errorResponse(status, action, code, message) {
6306
+ return {
6307
+ status,
6308
+ headers: { "content-type": "application/json" },
6309
+ body: {
6310
+ ok: false,
6311
+ action,
6312
+ output: { code, message }
6313
+ }
6314
+ };
6315
+ }
6066
6316
 
6067
6317
  // src/runtime.ts
6068
6318
  var InMemoryIntegrationGrantStore = class {
@@ -6718,6 +6968,8 @@ export {
6718
6968
  ResourceContention,
6719
6969
  StaticIntegrationPolicyEngine,
6720
6970
  TANGLE_CATALOG_RUNTIME_SIGNATURE_HEADER,
6971
+ TANGLE_INTEGRATIONS_CATALOG_PROVIDER_ID,
6972
+ TANGLE_INTEGRATIONS_CATALOG_SOURCE,
6721
6973
  TangleIntegrationsClient,
6722
6974
  _resetPendingFlowsForTests,
6723
6975
  adapterManifestsToConnectors,
@@ -6767,6 +7019,7 @@ export {
6767
7019
  createPlatformIntegrationPolicyPreset,
6768
7020
  createTangleCatalogExecutorProvider,
6769
7021
  createTangleCatalogHttpExecutor,
7022
+ createTangleCatalogRuntimeHandler,
6770
7023
  createTangleIntegrationsClient,
6771
7024
  declarativeRestConnector,
6772
7025
  decodeIntegrationBridgePayload,