@relayfile/sdk 0.1.3 → 0.1.5
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 +2 -0
- package/dist/client.d.ts +16 -1
- package/dist/client.js +32 -13
- package/dist/connection.d.ts +43 -0
- package/dist/connection.js +6 -0
- package/dist/index.d.ts +3 -6
- package/dist/index.js +1 -5
- package/dist/types.d.ts +21 -0
- package/package.json +1 -1
- package/dist/composio.d.ts +0 -63
- package/dist/composio.js +0 -233
- package/dist/nango.d.ts +0 -47
- package/dist/nango.js +0 -91
package/README.md
CHANGED
|
@@ -40,6 +40,8 @@ await client.writeFile({
|
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
42
|
|
|
43
|
+
Use a relayfile JWT whose claims include `workspace_id`, `agent_name`, and `aud: ["relayfile"]`. The SDK adds `X-Correlation-Id` automatically for API calls.
|
|
44
|
+
|
|
43
45
|
## Full Docs
|
|
44
46
|
|
|
45
47
|
Full documentation is available in the [relayfile docs](https://github.com/AgentWorkforce/relayfile/tree/main/docs).
|
package/dist/client.d.ts
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import { type AdminIngressStatusResponse, type AdminSyncStatusResponse, type BulkWriteInput, type BulkWriteResponse, type BackendStatusResponse, type AckResponse, type DeleteFileInput, type DeadLetterItem, type DeadLetterFeedResponse, type EventFeedResponse, type ExportJsonResponse, type ExportOptions, type FileQueryResponse, type FileReadResponse, type FilesystemEvent, type GetEventsOptions, type GetAdminIngressStatusOptions, type GetAdminSyncStatusOptions, type GetOperationsOptions, type GetSyncDeadLettersOptions, type GetSyncIngressStatusOptions, type GetSyncStatusOptions, type ListTreeOptions, type OperationFeedResponse, type OperationStatusResponse, type QueuedResponse, type QueryFilesOptions, type SyncIngressStatusResponse, type SyncStatusResponse, type TreeResponse, type WriteFileInput, type WriteQueuedResponse, type IngestWebhookInput, type WritebackItem, type AckWritebackInput, type AckWritebackResponse } from "./types.js";
|
|
2
|
+
/**
|
|
3
|
+
* Bearer token or token factory used for Relayfile API requests.
|
|
4
|
+
*
|
|
5
|
+
* When you mint JWTs for Relayfile, the server expects claims like:
|
|
6
|
+
* `{ workspace_id: "ws_123", agent_name: "review-bot", aud: ["relayfile"] }`
|
|
7
|
+
*/
|
|
2
8
|
export type AccessTokenProvider = string | (() => string | Promise<string>);
|
|
3
9
|
export interface RelayFileRetryOptions {
|
|
4
10
|
maxRetries?: number;
|
|
@@ -6,8 +12,17 @@ export interface RelayFileRetryOptions {
|
|
|
6
12
|
maxDelayMs?: number;
|
|
7
13
|
jitterRatio?: number;
|
|
8
14
|
}
|
|
15
|
+
/** Default base URL for the hosted Relayfile API */
|
|
16
|
+
export declare const DEFAULT_RELAYFILE_BASE_URL = "https://api.relayfile.dev";
|
|
9
17
|
export interface RelayFileClientOptions {
|
|
10
|
-
|
|
18
|
+
/** API base URL. Defaults to https://api.relayfile.dev */
|
|
19
|
+
baseUrl?: string;
|
|
20
|
+
/**
|
|
21
|
+
* Bearer token or token factory for SDK requests.
|
|
22
|
+
*
|
|
23
|
+
* Relayfile-authenticated JWTs should include `workspace_id`, `agent_name`,
|
|
24
|
+
* and `aud` containing `relayfile`.
|
|
25
|
+
*/
|
|
11
26
|
token: AccessTokenProvider;
|
|
12
27
|
fetchImpl?: typeof fetch;
|
|
13
28
|
userAgent?: string;
|
package/dist/client.js
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
2
|
+
/** Default base URL for the hosted Relayfile API */
|
|
3
|
+
export const DEFAULT_RELAYFILE_BASE_URL = "https://api.relayfile.dev";
|
|
2
4
|
const DEFAULT_RETRY_OPTIONS = {
|
|
3
5
|
maxRetries: 3,
|
|
4
6
|
baseDelayMs: 100,
|
|
@@ -28,7 +30,19 @@ function buildQuery(params) {
|
|
|
28
30
|
return encoded ? `?${encoded}` : "";
|
|
29
31
|
}
|
|
30
32
|
function generateCorrelationId() {
|
|
31
|
-
return `rf_${
|
|
33
|
+
return `rf_${crypto.randomUUID()}`;
|
|
34
|
+
}
|
|
35
|
+
function getHeaderValue(headers, name) {
|
|
36
|
+
if (!headers) {
|
|
37
|
+
return undefined;
|
|
38
|
+
}
|
|
39
|
+
const target = name.toLowerCase();
|
|
40
|
+
for (const [key, value] of Object.entries(headers)) {
|
|
41
|
+
if (key.toLowerCase() === target) {
|
|
42
|
+
return value;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
return undefined;
|
|
32
46
|
}
|
|
33
47
|
async function resolveToken(tokenProvider) {
|
|
34
48
|
if (typeof tokenProvider === "function") {
|
|
@@ -139,7 +153,7 @@ export class RelayFileClient {
|
|
|
139
153
|
userAgent;
|
|
140
154
|
retryOptions;
|
|
141
155
|
constructor(options) {
|
|
142
|
-
this.baseUrl = options.baseUrl.replace(/\/+$/, "");
|
|
156
|
+
this.baseUrl = (options.baseUrl ?? DEFAULT_RELAYFILE_BASE_URL).replace(/\/+$/, "");
|
|
143
157
|
this.tokenProvider = options.token;
|
|
144
158
|
this.fetchImpl = options.fetchImpl ?? fetch;
|
|
145
159
|
this.userAgent = options.userAgent;
|
|
@@ -200,21 +214,23 @@ export class RelayFileClient {
|
|
|
200
214
|
});
|
|
201
215
|
}
|
|
202
216
|
async writeFile(input) {
|
|
203
|
-
const
|
|
217
|
+
const { workspaceId, path, correlationId, baseRevision, content, contentType, encoding, semantics, signal } = input;
|
|
218
|
+
const query = buildQuery({ path });
|
|
204
219
|
return this.request({
|
|
205
220
|
method: "PUT",
|
|
206
|
-
path: `/v1/workspaces/${encodeURIComponent(
|
|
207
|
-
correlationId
|
|
221
|
+
path: `/v1/workspaces/${encodeURIComponent(workspaceId)}/fs/file${query}`,
|
|
222
|
+
correlationId,
|
|
208
223
|
headers: {
|
|
209
|
-
"If-Match":
|
|
224
|
+
"If-Match": baseRevision
|
|
210
225
|
},
|
|
226
|
+
// Single-file PUT expects the target path in the query string, not the JSON body.
|
|
211
227
|
body: {
|
|
212
|
-
contentType:
|
|
213
|
-
content
|
|
214
|
-
encoding
|
|
228
|
+
contentType: contentType ?? "text/markdown",
|
|
229
|
+
content,
|
|
230
|
+
encoding,
|
|
215
231
|
semantics: input.semantics
|
|
216
232
|
},
|
|
217
|
-
signal
|
|
233
|
+
signal
|
|
218
234
|
});
|
|
219
235
|
}
|
|
220
236
|
async bulkWrite(input) {
|
|
@@ -496,11 +512,14 @@ export class RelayFileClient {
|
|
|
496
512
|
return payload;
|
|
497
513
|
}
|
|
498
514
|
async performRequest(params) {
|
|
499
|
-
const
|
|
515
|
+
const existingCorrelationId = getHeaderValue(params.headers, "X-Correlation-Id");
|
|
516
|
+
const correlationId = existingCorrelationId ?? params.correlationId ?? generateCorrelationId();
|
|
500
517
|
const baseHeaders = {
|
|
501
|
-
|
|
502
|
-
...params.headers
|
|
518
|
+
...(params.headers ?? {})
|
|
503
519
|
};
|
|
520
|
+
if (!existingCorrelationId) {
|
|
521
|
+
baseHeaders["X-Correlation-Id"] = correlationId;
|
|
522
|
+
}
|
|
504
523
|
if (params.body !== undefined) {
|
|
505
524
|
baseHeaders["Content-Type"] = "application/json";
|
|
506
525
|
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared ConnectionProvider interface and related types.
|
|
3
|
+
*
|
|
4
|
+
* These types are the contract every provider package must implement.
|
|
5
|
+
*/
|
|
6
|
+
export type ProxyMethod = "DELETE" | "GET" | "PATCH" | "POST" | "PUT";
|
|
7
|
+
export type ProxyHeaders = Record<string, string>;
|
|
8
|
+
export type ProxyQuery = Record<string, string>;
|
|
9
|
+
/** Request sent through a connection provider's proxy. */
|
|
10
|
+
export interface ProxyRequest {
|
|
11
|
+
method: ProxyMethod;
|
|
12
|
+
/** Base API URL for the upstream service. */
|
|
13
|
+
baseUrl: string;
|
|
14
|
+
endpoint: string;
|
|
15
|
+
connectionId: string;
|
|
16
|
+
headers?: ProxyHeaders;
|
|
17
|
+
body?: unknown;
|
|
18
|
+
query?: ProxyQuery;
|
|
19
|
+
}
|
|
20
|
+
/** Response returned from a proxied request. */
|
|
21
|
+
export interface ProxyResponse<T = unknown> {
|
|
22
|
+
status: number;
|
|
23
|
+
headers: ProxyHeaders;
|
|
24
|
+
data: T;
|
|
25
|
+
}
|
|
26
|
+
/** Webhook normalized into a provider-agnostic shape. */
|
|
27
|
+
export interface NormalizedWebhook {
|
|
28
|
+
provider: string;
|
|
29
|
+
connectionId: string;
|
|
30
|
+
eventType: string;
|
|
31
|
+
objectType: string;
|
|
32
|
+
objectId: string;
|
|
33
|
+
payload: Record<string, unknown>;
|
|
34
|
+
}
|
|
35
|
+
/** Interface every connection provider must implement. */
|
|
36
|
+
export interface ConnectionProvider {
|
|
37
|
+
readonly name: string;
|
|
38
|
+
proxy<T = unknown>(request: ProxyRequest): Promise<ProxyResponse<T>>;
|
|
39
|
+
healthCheck(connectionId: string): Promise<boolean>;
|
|
40
|
+
handleWebhook?(rawPayload: unknown): Promise<NormalizedWebhook>;
|
|
41
|
+
getConnection?(connectionId: string): Promise<Record<string, unknown>>;
|
|
42
|
+
listConnections?(): Promise<Array<Record<string, unknown>>>;
|
|
43
|
+
}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,7 @@
|
|
|
1
|
-
export { RelayFileClient, type ConnectWebSocketOptions, type RelayFileRetryOptions, type WebSocketConnection } from "./client.js";
|
|
1
|
+
export { RelayFileClient, DEFAULT_RELAYFILE_BASE_URL, type AccessTokenProvider, type ConnectWebSocketOptions, type RelayFileClientOptions, type RelayFileRetryOptions, type WebSocketConnection } from "./client.js";
|
|
2
2
|
export { RelayFileSync, type RelayFileSyncOptions, type RelayFileSyncPong, type RelayFileSyncReconnectOptions, type RelayFileSyncSocket, type RelayFileSyncState } from "./sync.js";
|
|
3
3
|
export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
4
4
|
export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
|
|
5
5
|
export type { WebhookInput, ListProviderFilesOptions, WatchProviderEventsOptions } from "./provider.js";
|
|
6
|
-
export {
|
|
7
|
-
export type {
|
|
8
|
-
export { ComposioHelpers } from "./composio.js";
|
|
9
|
-
export type { ComposioWebhookPayload, ComposioTriggerOptions } from "./composio.js";
|
|
10
|
-
export type { AckResponse, AckWritebackInput, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ConflictErrorResponse, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, ErrorResponse, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackState, WritebackItem, WriteFileInput, WriteQueuedResponse } from "./types.js";
|
|
6
|
+
export type { ConnectionProvider, NormalizedWebhook, ProxyHeaders, ProxyMethod, ProxyQuery, ProxyRequest, ProxyResponse, } from "./connection.js";
|
|
7
|
+
export type { AckResponse, AckWritebackInput, AckWritebackResponse, AdminIngressAlert, AdminIngressAlertProfile, AdminIngressEffectiveAlertProfile, AdminIngressAlertSeverity, AdminIngressAlertThresholds, AdminIngressAlertTotals, AdminIngressAlertType, AdminIngressStatusResponse, AdminSyncAlert, AdminSyncAlertSeverity, AdminSyncAlertThresholds, AdminSyncAlertTotals, AdminSyncAlertType, AdminSyncStatusResponse, BackendStatusResponse, BulkWriteFile, BulkWriteInput, BulkWriteResponse, ConflictErrorResponse, DeleteFileInput, DeadLetterFeedResponse, DeadLetterItem, ErrorResponse, EventFeedResponse, ExportFormat, ExportJsonResponse, ExportOptions, FileQueryItem, FileQueryResponse, FileReadResponse, FileSemantics, FileWriteRequest, FilesystemEvent, FilesystemEventType, EventOrigin, GetEventsOptions, GetAdminSyncStatusOptions, GetAdminIngressStatusOptions, GetOperationsOptions, GetSyncDeadLettersOptions, GetSyncIngressStatusOptions, GetSyncStatusOptions, IngestWebhookInput, ListTreeOptions, OperationFeedResponse, OperationStatus, OperationStatusResponse, QueuedResponse, QueryFilesOptions, RelayFileJwtClaims, SyncIngressStatusResponse, SyncProviderStatus, SyncProviderStatusState, SyncRefreshRequest, SyncStatusResponse, TreeEntry, TreeResponse, WritebackActionType, WritebackState, WritebackItem, WriteFileInput, WriteQueuedResponse } from "./types.js";
|
package/dist/index.js
CHANGED
|
@@ -1,9 +1,5 @@
|
|
|
1
|
-
export { RelayFileClient } from "./client.js";
|
|
1
|
+
export { RelayFileClient, DEFAULT_RELAYFILE_BASE_URL } from "./client.js";
|
|
2
2
|
export { RelayFileSync } from "./sync.js";
|
|
3
3
|
export { InvalidStateError, PayloadTooLargeError, QueueFullError, RelayFileApiError, RevisionConflictError } from "./errors.js";
|
|
4
4
|
// Integration providers
|
|
5
5
|
export { IntegrationProvider, computeCanonicalPath } from "./provider.js";
|
|
6
|
-
// Nango bridge
|
|
7
|
-
export { NangoHelpers } from "./nango.js";
|
|
8
|
-
// Composio bridge
|
|
9
|
-
export { ComposioHelpers } from "./composio.js";
|
package/dist/types.d.ts
CHANGED
|
@@ -1,4 +1,25 @@
|
|
|
1
1
|
export type FileNodeType = "file" | "dir";
|
|
2
|
+
/**
|
|
3
|
+
* JWT claims expected by the Relayfile Go API when your token provider mints
|
|
4
|
+
* bearer tokens for SDK requests.
|
|
5
|
+
*
|
|
6
|
+
* Example minting payload:
|
|
7
|
+
* `const claims: RelayFileJwtClaims = { workspace_id: "ws_123", agent_name: "review-bot", aud: ["relayfile"] };`
|
|
8
|
+
*/
|
|
9
|
+
export interface RelayFileJwtClaims {
|
|
10
|
+
/** Workspace id the token is scoped to, for example `ws_123`. */
|
|
11
|
+
workspace_id: string;
|
|
12
|
+
/** Stable agent name presented to the Relayfile server, for example `review-bot`. */
|
|
13
|
+
agent_name: string;
|
|
14
|
+
/** Audience must contain `relayfile`. */
|
|
15
|
+
aud: "relayfile" | string[];
|
|
16
|
+
exp?: number;
|
|
17
|
+
iat?: number;
|
|
18
|
+
nbf?: number;
|
|
19
|
+
iss?: string;
|
|
20
|
+
sub?: string;
|
|
21
|
+
[claim: string]: unknown;
|
|
22
|
+
}
|
|
2
23
|
export interface TreeEntry {
|
|
3
24
|
path: string;
|
|
4
25
|
type: FileNodeType;
|
package/package.json
CHANGED
package/dist/composio.d.ts
DELETED
|
@@ -1,63 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composio integration bridge for Relayfile.
|
|
3
|
-
*
|
|
4
|
-
* Maps Composio trigger webhook events → Relayfile filesystem paths + semantics.
|
|
5
|
-
*
|
|
6
|
-
* Composio webhook payload format (V3):
|
|
7
|
-
* {
|
|
8
|
-
* "type": "composio.trigger.message",
|
|
9
|
-
* "metadata": {
|
|
10
|
-
* "trigger_slug": "GITHUB_COMMIT_EVENT",
|
|
11
|
-
* "trigger_id": "trig_abc123",
|
|
12
|
-
* "connected_account_id": "ca_xyz789",
|
|
13
|
-
* "user_id": "user_123",
|
|
14
|
-
* "toolkit": "github"
|
|
15
|
-
* },
|
|
16
|
-
* "data": {
|
|
17
|
-
* // trigger-specific payload (e.g., commit author, message, url)
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* @see https://docs.composio.dev/docs/triggers
|
|
22
|
-
* @see https://docs.composio.dev/docs/setting-up-triggers/subscribing-to-events
|
|
23
|
-
*/
|
|
24
|
-
import type { QueuedResponse } from "./types.js";
|
|
25
|
-
import { IntegrationProvider, type WebhookInput } from "./provider.js";
|
|
26
|
-
/** Raw webhook payload from Composio (V3 format) */
|
|
27
|
-
export interface ComposioWebhookPayload {
|
|
28
|
-
type: "composio.trigger.message" | "composio.connected_account.expired";
|
|
29
|
-
metadata: {
|
|
30
|
-
trigger_slug: string;
|
|
31
|
-
trigger_id: string;
|
|
32
|
-
connected_account_id: string;
|
|
33
|
-
user_id?: string;
|
|
34
|
-
toolkit: string;
|
|
35
|
-
};
|
|
36
|
-
data: Record<string, unknown>;
|
|
37
|
-
}
|
|
38
|
-
/** Options for creating Composio trigger subscriptions */
|
|
39
|
-
export interface ComposioTriggerOptions {
|
|
40
|
-
/** Composio API key */
|
|
41
|
-
apiKey: string;
|
|
42
|
-
/** Webhook URL to receive events */
|
|
43
|
-
webhookUrl: string;
|
|
44
|
-
/** Base URL for Composio API (default: https://backend.composio.dev) */
|
|
45
|
-
baseUrl?: string;
|
|
46
|
-
}
|
|
47
|
-
export declare class ComposioHelpers extends IntegrationProvider {
|
|
48
|
-
readonly name = "composio";
|
|
49
|
-
/**
|
|
50
|
-
* Ingest a Composio webhook payload into Relayfile.
|
|
51
|
-
*
|
|
52
|
-
* @param workspaceId - Relayfile workspace ID
|
|
53
|
-
* @param rawInput - Raw Composio webhook payload (ComposioWebhookPayload)
|
|
54
|
-
* @param signal - Optional abort signal
|
|
55
|
-
*/
|
|
56
|
-
ingestWebhook(workspaceId: string, rawInput: unknown, signal?: AbortSignal): Promise<QueuedResponse>;
|
|
57
|
-
/**
|
|
58
|
-
* Normalize a Composio webhook payload to the generic WebhookInput format.
|
|
59
|
-
* Useful for custom processing pipelines.
|
|
60
|
-
*/
|
|
61
|
-
normalize(input: ComposioWebhookPayload): WebhookInput;
|
|
62
|
-
private buildSemanticProperties;
|
|
63
|
-
}
|
package/dist/composio.js
DELETED
|
@@ -1,233 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Composio integration bridge for Relayfile.
|
|
3
|
-
*
|
|
4
|
-
* Maps Composio trigger webhook events → Relayfile filesystem paths + semantics.
|
|
5
|
-
*
|
|
6
|
-
* Composio webhook payload format (V3):
|
|
7
|
-
* {
|
|
8
|
-
* "type": "composio.trigger.message",
|
|
9
|
-
* "metadata": {
|
|
10
|
-
* "trigger_slug": "GITHUB_COMMIT_EVENT",
|
|
11
|
-
* "trigger_id": "trig_abc123",
|
|
12
|
-
* "connected_account_id": "ca_xyz789",
|
|
13
|
-
* "user_id": "user_123",
|
|
14
|
-
* "toolkit": "github"
|
|
15
|
-
* },
|
|
16
|
-
* "data": {
|
|
17
|
-
* // trigger-specific payload (e.g., commit author, message, url)
|
|
18
|
-
* }
|
|
19
|
-
* }
|
|
20
|
-
*
|
|
21
|
-
* @see https://docs.composio.dev/docs/triggers
|
|
22
|
-
* @see https://docs.composio.dev/docs/setting-up-triggers/subscribing-to-events
|
|
23
|
-
*/
|
|
24
|
-
import { IntegrationProvider, computeCanonicalPath, } from "./provider.js";
|
|
25
|
-
// ---------------------------------------------------------------------------
|
|
26
|
-
// Trigger slug → Relayfile object type mapping
|
|
27
|
-
// ---------------------------------------------------------------------------
|
|
28
|
-
/**
|
|
29
|
-
* Maps Composio trigger slugs to Relayfile object types.
|
|
30
|
-
* The trigger slug format is usually: {TOOLKIT}_{EVENT_NAME}
|
|
31
|
-
* e.g., GITHUB_COMMIT_EVENT → "commits", SLACK_NEW_MESSAGE → "messages"
|
|
32
|
-
*/
|
|
33
|
-
const TRIGGER_OBJECT_TYPE = {
|
|
34
|
-
// GitHub
|
|
35
|
-
GITHUB_COMMIT_EVENT: "commits",
|
|
36
|
-
GITHUB_PULL_REQUEST_EVENT: "pull_requests",
|
|
37
|
-
GITHUB_ISSUE_EVENT: "issues",
|
|
38
|
-
GITHUB_STAR_EVENT: "stars",
|
|
39
|
-
GITHUB_PUSH_EVENT: "pushes",
|
|
40
|
-
// Slack
|
|
41
|
-
SLACK_NEW_MESSAGE: "messages",
|
|
42
|
-
SLACK_CHANNEL_CREATED: "channels",
|
|
43
|
-
SLACK_REACTION_ADDED: "reactions",
|
|
44
|
-
// Gmail
|
|
45
|
-
GMAIL_NEW_EMAIL: "emails",
|
|
46
|
-
// Zendesk
|
|
47
|
-
ZENDESK_NEW_TICKET: "tickets",
|
|
48
|
-
ZENDESK_TICKET_UPDATED: "tickets",
|
|
49
|
-
// Shopify
|
|
50
|
-
SHOPIFY_NEW_ORDER: "orders",
|
|
51
|
-
SHOPIFY_ORDER_UPDATED: "orders",
|
|
52
|
-
// Stripe
|
|
53
|
-
STRIPE_PAYMENT_RECEIVED: "payments",
|
|
54
|
-
STRIPE_INVOICE_CREATED: "invoices",
|
|
55
|
-
// Jira
|
|
56
|
-
JIRA_ISSUE_CREATED: "issues",
|
|
57
|
-
JIRA_ISSUE_UPDATED: "issues",
|
|
58
|
-
// HubSpot
|
|
59
|
-
HUBSPOT_CONTACT_CREATED: "contacts",
|
|
60
|
-
HUBSPOT_DEAL_CREATED: "deals",
|
|
61
|
-
// Notion
|
|
62
|
-
NOTION_PAGE_UPDATED: "pages",
|
|
63
|
-
// Linear
|
|
64
|
-
LINEAR_ISSUE_CREATED: "issues",
|
|
65
|
-
LINEAR_ISSUE_UPDATED: "issues",
|
|
66
|
-
// Intercom
|
|
67
|
-
INTERCOM_NEW_CONVERSATION: "conversations",
|
|
68
|
-
// Freshdesk
|
|
69
|
-
FRESHDESK_TICKET_CREATED: "tickets",
|
|
70
|
-
FRESHDESK_TICKET_UPDATED: "tickets",
|
|
71
|
-
};
|
|
72
|
-
/**
|
|
73
|
-
* Extract event type (created/updated/deleted) from trigger slug.
|
|
74
|
-
*/
|
|
75
|
-
function extractEventType(triggerSlug) {
|
|
76
|
-
const slug = triggerSlug.toUpperCase();
|
|
77
|
-
if (slug.includes("CREATED") || slug.includes("NEW"))
|
|
78
|
-
return "created";
|
|
79
|
-
if (slug.includes("UPDATED") || slug.includes("CHANGED"))
|
|
80
|
-
return "updated";
|
|
81
|
-
if (slug.includes("DELETED") || slug.includes("REMOVED"))
|
|
82
|
-
return "deleted";
|
|
83
|
-
return "event";
|
|
84
|
-
}
|
|
85
|
-
/**
|
|
86
|
-
* Extract a stable object ID from Composio event data.
|
|
87
|
-
* Different triggers have different ID fields.
|
|
88
|
-
*/
|
|
89
|
-
function extractObjectId(data) {
|
|
90
|
-
// Common ID fields across various providers
|
|
91
|
-
const idFields = ["id", "objectId", "object_id", "ticketId", "issueId", "messageId", "orderId", "commitId"];
|
|
92
|
-
for (const field of idFields) {
|
|
93
|
-
const val = data[field];
|
|
94
|
-
if (typeof val === "string" || typeof val === "number") {
|
|
95
|
-
return String(val);
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
// Nested ID patterns
|
|
99
|
-
if (typeof data.issue === "object" && data.issue !== null && "id" in data.issue) {
|
|
100
|
-
return String(data.issue.id);
|
|
101
|
-
}
|
|
102
|
-
if (typeof data.pull_request === "object" && data.pull_request !== null && "id" in data.pull_request) {
|
|
103
|
-
return String(data.pull_request.id);
|
|
104
|
-
}
|
|
105
|
-
// Fallback: hash from trigger_id + timestamp
|
|
106
|
-
return `auto-${Date.now().toString(36)}`;
|
|
107
|
-
}
|
|
108
|
-
/**
|
|
109
|
-
* Infer the object type from trigger slug when not in the mapping table.
|
|
110
|
-
* Format: TOOLKIT_OBJECT_EVENT → "objects" (pluralized)
|
|
111
|
-
*/
|
|
112
|
-
function inferObjectType(triggerSlug) {
|
|
113
|
-
// Remove toolkit prefix and event suffix
|
|
114
|
-
const parts = triggerSlug.toLowerCase().split("_");
|
|
115
|
-
if (parts.length >= 3) {
|
|
116
|
-
// e.g., GITHUB_COMMIT_EVENT → "commit" → "commits"
|
|
117
|
-
const objectPart = parts.slice(1, -1).join("_");
|
|
118
|
-
return objectPart.endsWith("s") ? objectPart : `${objectPart}s`;
|
|
119
|
-
}
|
|
120
|
-
return "events";
|
|
121
|
-
}
|
|
122
|
-
// ---------------------------------------------------------------------------
|
|
123
|
-
// Composio provider implementation
|
|
124
|
-
// ---------------------------------------------------------------------------
|
|
125
|
-
export class ComposioHelpers extends IntegrationProvider {
|
|
126
|
-
name = "composio";
|
|
127
|
-
/**
|
|
128
|
-
* Ingest a Composio webhook payload into Relayfile.
|
|
129
|
-
*
|
|
130
|
-
* @param workspaceId - Relayfile workspace ID
|
|
131
|
-
* @param rawInput - Raw Composio webhook payload (ComposioWebhookPayload)
|
|
132
|
-
* @param signal - Optional abort signal
|
|
133
|
-
*/
|
|
134
|
-
async ingestWebhook(workspaceId, rawInput, signal) {
|
|
135
|
-
const input = rawInput;
|
|
136
|
-
if (input.type === "composio.connected_account.expired") {
|
|
137
|
-
// Handle account expiry as a system event
|
|
138
|
-
return this.client.ingestWebhook({
|
|
139
|
-
workspaceId,
|
|
140
|
-
provider: input.metadata.toolkit || "composio",
|
|
141
|
-
event_type: "account_expired",
|
|
142
|
-
path: `/.system/composio/expired/${input.metadata.connected_account_id}.json`,
|
|
143
|
-
data: {
|
|
144
|
-
connected_account_id: input.metadata.connected_account_id,
|
|
145
|
-
user_id: input.metadata.user_id,
|
|
146
|
-
toolkit: input.metadata.toolkit,
|
|
147
|
-
expired_at: new Date().toISOString(),
|
|
148
|
-
},
|
|
149
|
-
headers: {},
|
|
150
|
-
signal,
|
|
151
|
-
});
|
|
152
|
-
}
|
|
153
|
-
const toolkit = input.metadata.toolkit;
|
|
154
|
-
const triggerSlug = input.metadata.trigger_slug;
|
|
155
|
-
const objectType = TRIGGER_OBJECT_TYPE[triggerSlug] ?? inferObjectType(triggerSlug);
|
|
156
|
-
const objectId = extractObjectId(input.data);
|
|
157
|
-
const eventType = extractEventType(triggerSlug);
|
|
158
|
-
const path = computeCanonicalPath(toolkit, objectType, objectId);
|
|
159
|
-
const properties = this.buildSemanticProperties(input);
|
|
160
|
-
const semantics = {
|
|
161
|
-
properties,
|
|
162
|
-
relations: [],
|
|
163
|
-
};
|
|
164
|
-
return this.client.ingestWebhook({
|
|
165
|
-
workspaceId,
|
|
166
|
-
provider: toolkit,
|
|
167
|
-
event_type: eventType,
|
|
168
|
-
path,
|
|
169
|
-
data: {
|
|
170
|
-
...input.data,
|
|
171
|
-
semantics,
|
|
172
|
-
},
|
|
173
|
-
headers: {
|
|
174
|
-
"X-Composio-Trigger-Id": input.metadata.trigger_id,
|
|
175
|
-
"X-Composio-Trigger-Slug": triggerSlug,
|
|
176
|
-
"X-Composio-Connected-Account": input.metadata.connected_account_id,
|
|
177
|
-
...(input.metadata.user_id
|
|
178
|
-
? { "X-Composio-User-Id": input.metadata.user_id }
|
|
179
|
-
: {}),
|
|
180
|
-
},
|
|
181
|
-
signal,
|
|
182
|
-
});
|
|
183
|
-
}
|
|
184
|
-
/**
|
|
185
|
-
* Normalize a Composio webhook payload to the generic WebhookInput format.
|
|
186
|
-
* Useful for custom processing pipelines.
|
|
187
|
-
*/
|
|
188
|
-
normalize(input) {
|
|
189
|
-
const toolkit = input.metadata.toolkit;
|
|
190
|
-
const triggerSlug = input.metadata.trigger_slug;
|
|
191
|
-
return {
|
|
192
|
-
provider: toolkit,
|
|
193
|
-
objectType: TRIGGER_OBJECT_TYPE[triggerSlug] ?? inferObjectType(triggerSlug),
|
|
194
|
-
objectId: extractObjectId(input.data),
|
|
195
|
-
eventType: extractEventType(triggerSlug),
|
|
196
|
-
payload: input.data,
|
|
197
|
-
metadata: {
|
|
198
|
-
"composio.trigger_id": input.metadata.trigger_id,
|
|
199
|
-
"composio.trigger_slug": triggerSlug,
|
|
200
|
-
"composio.connected_account_id": input.metadata.connected_account_id,
|
|
201
|
-
...(input.metadata.user_id
|
|
202
|
-
? { "composio.user_id": input.metadata.user_id }
|
|
203
|
-
: {}),
|
|
204
|
-
},
|
|
205
|
-
};
|
|
206
|
-
}
|
|
207
|
-
buildSemanticProperties(input) {
|
|
208
|
-
const properties = {
|
|
209
|
-
"composio.trigger_id": input.metadata.trigger_id,
|
|
210
|
-
"composio.trigger_slug": input.metadata.trigger_slug,
|
|
211
|
-
"composio.connected_account_id": input.metadata.connected_account_id,
|
|
212
|
-
provider: input.metadata.toolkit,
|
|
213
|
-
"provider.object_type": TRIGGER_OBJECT_TYPE[input.metadata.trigger_slug] ??
|
|
214
|
-
inferObjectType(input.metadata.trigger_slug),
|
|
215
|
-
"provider.object_id": extractObjectId(input.data),
|
|
216
|
-
};
|
|
217
|
-
if (input.metadata.user_id) {
|
|
218
|
-
properties["composio.user_id"] = input.metadata.user_id;
|
|
219
|
-
}
|
|
220
|
-
// Extract common fields from data
|
|
221
|
-
const data = input.data;
|
|
222
|
-
if (typeof data.status === "string") {
|
|
223
|
-
properties["provider.status"] = data.status;
|
|
224
|
-
}
|
|
225
|
-
if (typeof data.updated_at === "string") {
|
|
226
|
-
properties["provider.updated_at"] = data.updated_at;
|
|
227
|
-
}
|
|
228
|
-
if (typeof data.created_at === "string") {
|
|
229
|
-
properties["provider.created_at"] = data.created_at;
|
|
230
|
-
}
|
|
231
|
-
return properties;
|
|
232
|
-
}
|
|
233
|
-
}
|
package/dist/nango.d.ts
DELETED
|
@@ -1,47 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nango integration bridge for Relayfile.
|
|
3
|
-
*
|
|
4
|
-
* Maps Nango sync webhook events → Relayfile filesystem paths + semantics.
|
|
5
|
-
*
|
|
6
|
-
* @see https://docs.nango.dev/integrate/guides/receive-webhooks-from-nango
|
|
7
|
-
*/
|
|
8
|
-
import type { QueuedResponse } from "./types.js";
|
|
9
|
-
import { IntegrationProvider, type WebhookInput } from "./provider.js";
|
|
10
|
-
export interface NangoWebhookInput {
|
|
11
|
-
connectionId: string;
|
|
12
|
-
integrationId: string;
|
|
13
|
-
providerConfigKey?: string;
|
|
14
|
-
model: string;
|
|
15
|
-
objectId: string;
|
|
16
|
-
eventType: string;
|
|
17
|
-
payload: Record<string, unknown>;
|
|
18
|
-
relations?: string[];
|
|
19
|
-
}
|
|
20
|
-
export interface GetProviderFilesOptions {
|
|
21
|
-
provider: string;
|
|
22
|
-
objectType?: string;
|
|
23
|
-
status?: string;
|
|
24
|
-
limit?: number;
|
|
25
|
-
signal?: AbortSignal;
|
|
26
|
-
}
|
|
27
|
-
export interface WatchProviderEventsOptions {
|
|
28
|
-
provider: string;
|
|
29
|
-
pollIntervalMs?: number;
|
|
30
|
-
cursor?: string;
|
|
31
|
-
signal?: AbortSignal;
|
|
32
|
-
}
|
|
33
|
-
export declare class NangoHelpers extends IntegrationProvider {
|
|
34
|
-
readonly name = "nango";
|
|
35
|
-
/**
|
|
36
|
-
* Ingest a Nango webhook event into Relayfile.
|
|
37
|
-
*
|
|
38
|
-
* @param workspaceId - Relayfile workspace ID
|
|
39
|
-
* @param rawInput - NangoWebhookInput
|
|
40
|
-
* @param signal - Optional abort signal
|
|
41
|
-
*/
|
|
42
|
-
ingestWebhook(workspaceId: string, rawInput: unknown, signal?: AbortSignal): Promise<QueuedResponse>;
|
|
43
|
-
/**
|
|
44
|
-
* Normalize a Nango webhook input to the generic WebhookInput format.
|
|
45
|
-
*/
|
|
46
|
-
normalize(input: NangoWebhookInput): WebhookInput;
|
|
47
|
-
}
|
package/dist/nango.js
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Nango integration bridge for Relayfile.
|
|
3
|
-
*
|
|
4
|
-
* Maps Nango sync webhook events → Relayfile filesystem paths + semantics.
|
|
5
|
-
*
|
|
6
|
-
* @see https://docs.nango.dev/integrate/guides/receive-webhooks-from-nango
|
|
7
|
-
*/
|
|
8
|
-
import { IntegrationProvider, computeCanonicalPath, } from "./provider.js";
|
|
9
|
-
// ---------------------------------------------------------------------------
|
|
10
|
-
// Nango provider implementation
|
|
11
|
-
// ---------------------------------------------------------------------------
|
|
12
|
-
function buildSemanticProperties(provider, input, payload) {
|
|
13
|
-
const properties = {
|
|
14
|
-
"nango.connection_id": input.connectionId,
|
|
15
|
-
"nango.integration_id": input.integrationId,
|
|
16
|
-
"provider": provider,
|
|
17
|
-
"provider.object_type": input.model,
|
|
18
|
-
"provider.object_id": input.objectId
|
|
19
|
-
};
|
|
20
|
-
if (input.providerConfigKey) {
|
|
21
|
-
properties["nango.provider_config_key"] = input.providerConfigKey;
|
|
22
|
-
}
|
|
23
|
-
if (typeof payload.status === "string") {
|
|
24
|
-
properties["provider.status"] = payload.status;
|
|
25
|
-
}
|
|
26
|
-
if (typeof payload.updated_at === "string") {
|
|
27
|
-
properties["provider.updated_at"] = payload.updated_at;
|
|
28
|
-
}
|
|
29
|
-
if (typeof payload.created_at === "string") {
|
|
30
|
-
properties["provider.created_at"] = payload.created_at;
|
|
31
|
-
}
|
|
32
|
-
return properties;
|
|
33
|
-
}
|
|
34
|
-
export class NangoHelpers extends IntegrationProvider {
|
|
35
|
-
name = "nango";
|
|
36
|
-
/**
|
|
37
|
-
* Ingest a Nango webhook event into Relayfile.
|
|
38
|
-
*
|
|
39
|
-
* @param workspaceId - Relayfile workspace ID
|
|
40
|
-
* @param rawInput - NangoWebhookInput
|
|
41
|
-
* @param signal - Optional abort signal
|
|
42
|
-
*/
|
|
43
|
-
async ingestWebhook(workspaceId, rawInput, signal) {
|
|
44
|
-
const input = rawInput;
|
|
45
|
-
const provider = input.integrationId.split("-")[0] ?? input.integrationId;
|
|
46
|
-
const path = computeCanonicalPath(provider, input.model, input.objectId);
|
|
47
|
-
const properties = buildSemanticProperties(provider, input, input.payload);
|
|
48
|
-
return this.client.ingestWebhook({
|
|
49
|
-
workspaceId,
|
|
50
|
-
provider: provider,
|
|
51
|
-
event_type: input.eventType,
|
|
52
|
-
path,
|
|
53
|
-
data: {
|
|
54
|
-
...input.payload,
|
|
55
|
-
semantics: {
|
|
56
|
-
properties,
|
|
57
|
-
relations: input.relations ?? []
|
|
58
|
-
}
|
|
59
|
-
},
|
|
60
|
-
headers: {
|
|
61
|
-
"X-Nango-Connection-Id": input.connectionId,
|
|
62
|
-
"X-Nango-Integration-Id": input.integrationId,
|
|
63
|
-
...(input.providerConfigKey
|
|
64
|
-
? { "X-Nango-Provider-Config-Key": input.providerConfigKey }
|
|
65
|
-
: {})
|
|
66
|
-
},
|
|
67
|
-
signal
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
|
-
/**
|
|
71
|
-
* Normalize a Nango webhook input to the generic WebhookInput format.
|
|
72
|
-
*/
|
|
73
|
-
normalize(input) {
|
|
74
|
-
const provider = input.integrationId.split("-")[0] ?? input.integrationId;
|
|
75
|
-
return {
|
|
76
|
-
provider,
|
|
77
|
-
objectType: input.model,
|
|
78
|
-
objectId: input.objectId,
|
|
79
|
-
eventType: input.eventType,
|
|
80
|
-
payload: input.payload,
|
|
81
|
-
relations: input.relations,
|
|
82
|
-
metadata: {
|
|
83
|
-
"nango.connection_id": input.connectionId,
|
|
84
|
-
"nango.integration_id": input.integrationId,
|
|
85
|
-
...(input.providerConfigKey
|
|
86
|
-
? { "nango.provider_config_key": input.providerConfigKey }
|
|
87
|
-
: {}),
|
|
88
|
-
},
|
|
89
|
-
};
|
|
90
|
-
}
|
|
91
|
-
}
|