@tangle-network/agent-integrations 0.3.0 → 0.4.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/index.d.ts CHANGED
@@ -533,6 +533,25 @@ interface GenericHmacVerifyOptions {
533
533
  lowercaseHex?: boolean;
534
534
  }
535
535
  declare function verifyHmacSignature(rawBody: string, signatureHeader: string, secret: string, options?: GenericHmacVerifyOptions): boolean;
536
+ interface TwilioVerifyOptions {
537
+ /** Skip verification when the auth token isn't configured. Useful in
538
+ * dev where the receiver wants to accept any payload. Default `false`
539
+ * — production should always require a configured token. */
540
+ skipWhenAuthTokenMissing?: boolean;
541
+ /** When true, sign the raw body instead of the URL-encoded sorted-params
542
+ * reduction. Twilio uses raw-body signing for `application/json`
543
+ * webhook bodies. Default `false`. */
544
+ bodyAsRaw?: boolean;
545
+ /** When `bodyAsRaw` is true, the raw body to sign. Ignored otherwise. */
546
+ rawBody?: string;
547
+ }
548
+ /** Verify a Twilio webhook signature. */
549
+ declare function verifyTwilioSignature(input: {
550
+ authToken: string | null | undefined;
551
+ signatureHeader: string | string[] | undefined;
552
+ fullUrl: string | null | undefined;
553
+ params: Record<string, string> | undefined;
554
+ }, options?: TwilioVerifyOptions): boolean;
536
555
  declare function firstHeader(headers: Record<string, string | string[] | undefined>, name: string): string | undefined;
537
556
 
538
557
  /**
@@ -1049,6 +1068,60 @@ interface ConnectorAdapterProviderOptions {
1049
1068
  declare function createConnectorAdapterProvider(options: ConnectorAdapterProviderOptions): IntegrationProvider;
1050
1069
  declare function manifestToConnector(providerId: string, adapter: ConnectorAdapter): IntegrationConnector;
1051
1070
 
1071
+ interface ImportCatalogOptions {
1072
+ providerId: string;
1073
+ connectorId: string;
1074
+ connectorTitle: string;
1075
+ category?: IntegrationConnectorCategory;
1076
+ auth?: IntegrationConnector['auth'];
1077
+ scopes?: string[];
1078
+ dataClass?: IntegrationDataClass;
1079
+ defaultRisk?: IntegrationActionRisk;
1080
+ }
1081
+ interface OpenApiDocument {
1082
+ openapi?: string;
1083
+ swagger?: string;
1084
+ info?: {
1085
+ title?: string;
1086
+ };
1087
+ paths?: Record<string, Record<string, OpenApiOperation | unknown>>;
1088
+ }
1089
+ interface OpenApiOperation {
1090
+ operationId?: string;
1091
+ summary?: string;
1092
+ description?: string;
1093
+ parameters?: unknown[];
1094
+ requestBody?: unknown;
1095
+ responses?: unknown;
1096
+ security?: Array<Record<string, string[]>>;
1097
+ tags?: string[];
1098
+ }
1099
+ interface GraphqlOperationSpec {
1100
+ name: string;
1101
+ kind: 'query' | 'mutation';
1102
+ description?: string;
1103
+ inputSchema?: unknown;
1104
+ outputSchema?: unknown;
1105
+ requiredScopes?: string[];
1106
+ }
1107
+ interface McpCatalogTool {
1108
+ name: string;
1109
+ description?: string;
1110
+ inputSchema?: unknown;
1111
+ annotations?: {
1112
+ readOnlyHint?: boolean;
1113
+ destructiveHint?: boolean;
1114
+ openWorldHint?: boolean;
1115
+ title?: string;
1116
+ };
1117
+ }
1118
+ interface McpCatalog {
1119
+ tools: McpCatalogTool[];
1120
+ }
1121
+ declare function importOpenApiConnector(document: OpenApiDocument, options: ImportCatalogOptions): IntegrationConnector;
1122
+ declare function importGraphqlConnector(operations: GraphqlOperationSpec[], options: ImportCatalogOptions): IntegrationConnector;
1123
+ declare function importMcpConnector(catalog: McpCatalog, options: ImportCatalogOptions): IntegrationConnector;
1124
+
1052
1125
  type IntegrationProviderKind = 'first_party' | 'nango' | 'pipedream' | 'zapier' | 'activepieces' | 'executor' | 'custom';
1053
1126
  type IntegrationConnectorCategory = 'email' | 'calendar' | 'chat' | 'crm' | 'storage' | 'docs' | 'database' | 'webhook' | 'workflow' | 'internal' | 'other';
1054
1127
  type IntegrationActionRisk = 'read' | 'write' | 'destructive';
@@ -1345,4 +1418,4 @@ declare function createHttpIntegrationProvider(options: HttpIntegrationProviderO
1345
1418
  declare function signCapability(capability: IntegrationCapability, secret: string): string;
1346
1419
  declare function verifyCapabilityToken(token: string, secret: string): IntegrationCapability;
1347
1420
 
1348
- export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorAdapterProviderOptions, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type HttpIntegrationProviderOptions, type HubSpotOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationApprovalRequest, type IntegrationApprovalResolution, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationInvocationEnvelope, type IntegrationPolicyDecision, type IntegrationPolicyEffect, type IntegrationPolicyEngine, type IntegrationPolicyRule, type IntegrationProvider, type IntegrationProviderKind, type IntegrationToolDefinition, type IntegrationToolSearchFilters, type IntegrationToolSearchResult, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, StaticIntegrationPolicyEngine, type StaticIntegrationPolicyOptions, type StripeVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, integrationToolName, invocationRequestFromEnvelope, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, webhookConnector };
1421
+ export { type AuthSpec, type CASStrategy, type Capability, type CapabilityClass, type CapabilityMutation, type CapabilityMutationResult, type CapabilityParameterSchema, type CapabilityRead, type CapabilityReadResult, type CompleteAuthRequest, type ConnectorAdapter, type ConnectorAdapterProviderOptions, type ConnectorCredentials, type ConnectorInvocation, type ConnectorManifest, type ConnectorManifestValidationIssue, type ConnectorManifestValidationResult, type ConsistencyModel, CredentialsExpired, DEFAULT_SIGNATURE_TOLERANCE_SECONDS, type DataSourceMetadata, type EventHandlerResult, type ExchangeCodeInput, type GenericHmacVerifyOptions, type GoogleCalendarOptions, type GoogleSheetsOptions, type GraphqlOperationSpec, type HttpIntegrationProviderOptions, type HubSpotOptions, type ImportCatalogOptions, InMemoryConnectionStore, InMemoryOAuthFlowStore, type InboundEvent, type IntegrationActionGuard, type IntegrationActionRequest, type IntegrationActionResult, type IntegrationActionRisk, type IntegrationActor, type IntegrationApprovalRequest, type IntegrationApprovalResolution, type IntegrationCapability, type IntegrationConnection, type IntegrationConnectionStore, type IntegrationConnector, type IntegrationConnectorAction, type IntegrationConnectorCategory, type IntegrationConnectorTrigger, type IntegrationDataClass, IntegrationError, type IntegrationGuardContext, IntegrationHub, type IntegrationHubOptions, type IntegrationInvocationEnvelope, type IntegrationPolicyDecision, type IntegrationPolicyEffect, type IntegrationPolicyEngine, type IntegrationPolicyRule, type IntegrationProvider, type IntegrationProviderKind, type IntegrationToolDefinition, type IntegrationToolSearchFilters, type IntegrationToolSearchResult, type IntegrationTriggerEvent, type IntegrationTriggerSubscription, type InvokeWithCapabilityRequest, type IssueCapabilityRequest, type IssuedIntegrationCapability, type McpCatalog, type McpCatalogTool, type McpToolDefinition, type MicrosoftCalendarOptions, type NormalizedIntegrationResult, type NotionDatabaseOptions, type OAuthFlowStore, type OAuthTokens, type OpenApiDocument, type OpenApiOperation, type ParsedStripeSignatureHeader, type PendingOAuthFlow, type RateLimitSpec, type RefreshInput, type ResolvedDataSource, ResourceContention, type SecretRef, type SlackOptions, type SlackVerifyOptions, type StartAuthRequest, type StartAuthResult, type StartOAuthInput, type StartOAuthOutput, StaticIntegrationPolicyEngine, type StaticIntegrationPolicyOptions, type StripeVerifyOptions, type TwilioVerifyOptions, _resetPendingFlowsForTests, assertValidConnectorManifest, buildApprovalRequest, buildIntegrationInvocationEnvelope, buildIntegrationToolCatalog, consumePendingFlow, createConnectorAdapterProvider, createDefaultIntegrationPolicyEngine, createHttpIntegrationProvider, createMockIntegrationProvider, exchangeAuthorizationCode, firstHeader, googleCalendar, googleSheets, hubspot, importGraphqlConnector, importMcpConnector, importOpenApiConnector, integrationToolName, invocationRequestFromEnvelope, manifestToConnector, microsoftCalendar, normalizeIntegrationResult, notionDatabase, parseIntegrationToolName, parseStripeSignatureHeader, redactApprovalRequest, redactCapability, redactInvocationEnvelope, refreshAccessToken, sanitizeConnection, searchIntegrationTools, signCapability, slack, slackEventsConnector, startOAuthFlow, stripePackConnector, stripeWebhookReceiverConnector, toMcpTools, twilioSmsConnector, validateConnectorManifest, verifyCapabilityToken, verifyHmacSignature, verifySlackSignature, verifyStripeSignature, verifyTwilioSignature, webhookConnector };
package/dist/index.js CHANGED
@@ -242,6 +242,20 @@ function verifyHmacSignature(rawBody, signatureHeader, secret, options = {}) {
242
242
  if (sigBuf.length !== expectedBuf.length) return false;
243
243
  return timingSafeEqual(sigBuf, expectedBuf);
244
244
  }
245
+ function verifyTwilioSignature(input, options = {}) {
246
+ if (!input.authToken) {
247
+ return options.skipWhenAuthTokenMissing === true;
248
+ }
249
+ const signature = input.signatureHeader;
250
+ if (!signature || Array.isArray(signature)) return false;
251
+ if (!input.fullUrl) return false;
252
+ const data = options.bodyAsRaw === true ? input.fullUrl + (options.rawBody ?? "") : Object.keys(input.params ?? {}).sort().reduce((acc, key) => acc + key + (input.params[key] ?? ""), input.fullUrl);
253
+ const expected = createHmac("sha1", input.authToken).update(data).digest("base64");
254
+ const expectedBuf = Buffer.from(expected);
255
+ const sigBuf = Buffer.from(signature);
256
+ if (expectedBuf.length !== sigBuf.length) return false;
257
+ return timingSafeEqual(expectedBuf, sigBuf);
258
+ }
245
259
  function firstHeader(headers, name) {
246
260
  const v = headers[name] ?? headers[name.toLowerCase()] ?? Object.entries(headers).find(([key]) => key.toLowerCase() === name.toLowerCase())?.[1];
247
261
  if (Array.isArray(v)) return v[0];
@@ -3068,6 +3082,116 @@ function toRecord(input) {
3068
3082
  return {};
3069
3083
  }
3070
3084
 
3085
+ // src/importers.ts
3086
+ var HTTP_METHODS = /* @__PURE__ */ new Set(["get", "post", "put", "patch", "delete"]);
3087
+ function importOpenApiConnector(document, options) {
3088
+ const actions = [];
3089
+ for (const [path, methods] of Object.entries(document.paths ?? {})) {
3090
+ for (const [method, rawOperation] of Object.entries(methods)) {
3091
+ const normalizedMethod = method.toLowerCase();
3092
+ if (!HTTP_METHODS.has(normalizedMethod) || !isObject(rawOperation)) continue;
3093
+ const operation = rawOperation;
3094
+ const operationId = operation.operationId ?? `${normalizedMethod}_${path.replace(/[^a-zA-Z0-9]+/g, "_").replace(/^_+|_+$/g, "")}`;
3095
+ actions.push({
3096
+ id: operationId,
3097
+ title: operation.summary ?? titleFromId(operationId),
3098
+ risk: riskFromHttpMethod(normalizedMethod, operation, options.defaultRisk),
3099
+ requiredScopes: scopesFromOpenApiOperation(operation, options.scopes ?? []),
3100
+ dataClass: options.dataClass ?? "private",
3101
+ description: operation.description ?? operation.summary ?? `${normalizedMethod.toUpperCase()} ${path}`,
3102
+ approvalRequired: riskFromHttpMethod(normalizedMethod, operation, options.defaultRisk) !== "read",
3103
+ inputSchema: openApiInputSchema(path, normalizedMethod, operation),
3104
+ outputSchema: operation.responses
3105
+ });
3106
+ }
3107
+ }
3108
+ return connectorFromActions(options, actions);
3109
+ }
3110
+ function importGraphqlConnector(operations, options) {
3111
+ return connectorFromActions(options, operations.map((operation) => ({
3112
+ id: operation.name,
3113
+ title: titleFromId(operation.name),
3114
+ risk: operation.kind === "query" ? "read" : options.defaultRisk ?? "write",
3115
+ requiredScopes: operation.requiredScopes ?? options.scopes ?? [],
3116
+ dataClass: options.dataClass ?? "private",
3117
+ description: operation.description,
3118
+ approvalRequired: operation.kind === "mutation",
3119
+ inputSchema: operation.inputSchema,
3120
+ outputSchema: operation.outputSchema
3121
+ })));
3122
+ }
3123
+ function importMcpConnector(catalog, options) {
3124
+ return connectorFromActions(options, catalog.tools.map((tool) => {
3125
+ const risk = riskFromMcpTool(tool, options.defaultRisk);
3126
+ return {
3127
+ id: tool.name,
3128
+ title: tool.annotations?.title ?? titleFromId(tool.name),
3129
+ risk,
3130
+ requiredScopes: options.scopes ?? [],
3131
+ dataClass: options.dataClass ?? "private",
3132
+ description: tool.description,
3133
+ approvalRequired: risk !== "read",
3134
+ inputSchema: tool.inputSchema
3135
+ };
3136
+ }));
3137
+ }
3138
+ function connectorFromActions(options, actions) {
3139
+ const scopes = unique2([
3140
+ ...options.scopes ?? [],
3141
+ ...actions.flatMap((action) => action.requiredScopes)
3142
+ ]);
3143
+ return {
3144
+ id: options.connectorId,
3145
+ providerId: options.providerId,
3146
+ title: options.connectorTitle,
3147
+ category: options.category ?? "other",
3148
+ auth: options.auth ?? "custom",
3149
+ scopes,
3150
+ actions,
3151
+ metadata: { source: "catalog-importer" }
3152
+ };
3153
+ }
3154
+ function riskFromHttpMethod(method, operation, fallback) {
3155
+ if (method === "get") return "read";
3156
+ if (method === "delete") return "destructive";
3157
+ const text = `${operation.operationId ?? ""} ${operation.summary ?? ""} ${operation.description ?? ""}`.toLowerCase();
3158
+ if (/\b(delete|remove|destroy|cancel|void|revoke|drop)\b/.test(text)) return "destructive";
3159
+ return fallback && fallback !== "read" ? fallback : "write";
3160
+ }
3161
+ function riskFromMcpTool(tool, fallback) {
3162
+ if (tool.annotations?.destructiveHint) return "destructive";
3163
+ if (tool.annotations?.readOnlyHint) return "read";
3164
+ const text = `${tool.name} ${tool.description ?? ""}`.toLowerCase();
3165
+ if (/\b(delete|remove|destroy|cancel|void|revoke|drop)\b/.test(text)) return "destructive";
3166
+ if (/\b(get|list|read|search|find|fetch|query)\b/.test(text)) return "read";
3167
+ return fallback ?? "write";
3168
+ }
3169
+ function scopesFromOpenApiOperation(operation, fallback) {
3170
+ const scopes = (operation.security ?? []).flatMap((entry) => Object.values(entry).flat());
3171
+ return unique2(scopes.length > 0 ? scopes : fallback);
3172
+ }
3173
+ function openApiInputSchema(path, method, operation) {
3174
+ return {
3175
+ type: "object",
3176
+ additionalProperties: true,
3177
+ properties: {
3178
+ path: { const: path },
3179
+ method: { const: method.toUpperCase() },
3180
+ parameters: { type: "object", additionalProperties: true },
3181
+ body: operation.requestBody ?? { type: "object", additionalProperties: true }
3182
+ }
3183
+ };
3184
+ }
3185
+ function titleFromId(id) {
3186
+ return id.replace(/([a-z])([A-Z])/g, "$1 $2").split(/[^a-zA-Z0-9]+/g).filter(Boolean).map((part) => part.slice(0, 1).toUpperCase() + part.slice(1)).join(" ");
3187
+ }
3188
+ function isObject(value) {
3189
+ return Boolean(value) && typeof value === "object" && !Array.isArray(value);
3190
+ }
3191
+ function unique2(values) {
3192
+ return [...new Set(values)];
3193
+ }
3194
+
3071
3195
  // src/index.ts
3072
3196
  var IntegrationError = class extends Error {
3073
3197
  constructor(message, code) {
@@ -3142,8 +3266,8 @@ var IntegrationHub = class {
3142
3266
  id: `cap_${randomUUID2()}`,
3143
3267
  subject: request.subject,
3144
3268
  connectionId: request.connectionId,
3145
- scopes: unique2(request.scopes),
3146
- allowedActions: unique2(request.allowedActions),
3269
+ scopes: unique3(request.scopes),
3270
+ allowedActions: unique3(request.allowedActions),
3147
3271
  issuedAt: now.toISOString(),
3148
3272
  expiresAt: new Date(now.getTime() + request.ttlMs).toISOString(),
3149
3273
  metadata: request.metadata
@@ -3389,7 +3513,7 @@ function base64UrlEncode(value) {
3389
3513
  function base64UrlDecode(value) {
3390
3514
  return Buffer.from(value, "base64url").toString("utf8");
3391
3515
  }
3392
- function unique2(values) {
3516
+ function unique3(values) {
3393
3517
  return [...new Set(values)];
3394
3518
  }
3395
3519
  export {
@@ -3416,6 +3540,9 @@ export {
3416
3540
  googleCalendar,
3417
3541
  googleSheets,
3418
3542
  hubspot,
3543
+ importGraphqlConnector,
3544
+ importMcpConnector,
3545
+ importOpenApiConnector,
3419
3546
  integrationToolName,
3420
3547
  invocationRequestFromEnvelope,
3421
3548
  manifestToConnector,
@@ -3443,6 +3570,7 @@ export {
3443
3570
  verifyHmacSignature,
3444
3571
  verifySlackSignature,
3445
3572
  verifyStripeSignature,
3573
+ verifyTwilioSignature,
3446
3574
  webhookConnector
3447
3575
  };
3448
3576
  //# sourceMappingURL=index.js.map