@reactor-cloud/connect 0.2.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.cjs +122 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +290 -0
- package/dist/index.d.ts +290 -0
- package/dist/index.js +119 -0
- package/dist/index.js.map +1 -0
- package/package.json +49 -0
package/README.md
ADDED
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# @reactor-cloud/connect
|
|
2
|
+
|
|
3
|
+
Connect client for Reactor. Manage connector instances, invoke actions, and configure webhook receivers.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @reactor-cloud/connect @reactor-cloud/shared
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Or use the unified client:
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install @reactor-cloud/client
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```typescript
|
|
20
|
+
import { createClient } from '@reactor-cloud/client';
|
|
21
|
+
|
|
22
|
+
const reactor = createClient('https://reactor.cloud', { key: 'rk_pub_...' });
|
|
23
|
+
|
|
24
|
+
// Browse the catalog
|
|
25
|
+
const { data: connectors } = await reactor.connect.catalog.list();
|
|
26
|
+
|
|
27
|
+
// Create an instance
|
|
28
|
+
const { data: instance } = await reactor.connect.instances.create('stripe', {
|
|
29
|
+
name: 'stripe-prod',
|
|
30
|
+
config: { api_key: 'sk_test_...' },
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Invoke an action (with optional dry-run / idempotency key)
|
|
34
|
+
const { data: result } = await reactor.connect.invoke(instance!.id, 'createCustomer', {
|
|
35
|
+
input: { email: 'user@example.com' },
|
|
36
|
+
dryRun: true,
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
// Register a webhook receiver
|
|
40
|
+
const { data: receiver } = await reactor.connect.receivers.create({
|
|
41
|
+
name: 'stripe-events',
|
|
42
|
+
target: { type: 'job', name: 'handle-stripe' },
|
|
43
|
+
});
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## License
|
|
47
|
+
|
|
48
|
+
MIT
|
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,122 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var shared = require('@reactor-cloud/shared');
|
|
4
|
+
|
|
5
|
+
// src/index.ts
|
|
6
|
+
var ConnectClient = class {
|
|
7
|
+
constructor(ctx) {
|
|
8
|
+
this.ctx = ctx;
|
|
9
|
+
}
|
|
10
|
+
ctx;
|
|
11
|
+
// ----------------------------------------
|
|
12
|
+
// Catalog
|
|
13
|
+
// ----------------------------------------
|
|
14
|
+
/** Access the connector catalog. */
|
|
15
|
+
get catalog() {
|
|
16
|
+
return {
|
|
17
|
+
/** List available connectors. */
|
|
18
|
+
list: async () => shared.get(this.ctx, "/connect/v1/catalog"),
|
|
19
|
+
/** Get connector details. */
|
|
20
|
+
get: async (connectorType) => shared.get(this.ctx, `/connect/v1/catalog/${encodeURIComponent(connectorType)}`)
|
|
21
|
+
};
|
|
22
|
+
}
|
|
23
|
+
// ----------------------------------------
|
|
24
|
+
// Instances
|
|
25
|
+
// ----------------------------------------
|
|
26
|
+
/** Manage connector instances. */
|
|
27
|
+
get instances() {
|
|
28
|
+
return {
|
|
29
|
+
/** List instances. */
|
|
30
|
+
list: async (options) => {
|
|
31
|
+
const params = new URLSearchParams();
|
|
32
|
+
if (options?.connectorType) params.set("connector_type", options.connectorType);
|
|
33
|
+
if (options?.status) params.set("status", options.status);
|
|
34
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
35
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
36
|
+
const query = params.toString();
|
|
37
|
+
return shared.get(this.ctx, `/connect/v1/instances${query ? "?" + query : ""}`);
|
|
38
|
+
},
|
|
39
|
+
/** Create a new instance. */
|
|
40
|
+
create: async (connectorType, options) => shared.post(this.ctx, "/connect/v1/instances", {
|
|
41
|
+
connector_type: connectorType,
|
|
42
|
+
name: options.name,
|
|
43
|
+
config: options.config ?? {}
|
|
44
|
+
}),
|
|
45
|
+
/** Get instance details. */
|
|
46
|
+
get: async (instanceId) => shared.get(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),
|
|
47
|
+
/** Update an instance. */
|
|
48
|
+
update: async (instanceId, options) => shared.patch(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`, options),
|
|
49
|
+
/** Delete an instance. */
|
|
50
|
+
delete: async (instanceId) => shared.del(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),
|
|
51
|
+
/** Test instance credentials. */
|
|
52
|
+
check: async (instanceId) => shared.post(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}/check`, {}),
|
|
53
|
+
/** Set credentials for an instance. */
|
|
54
|
+
setCredentials: async (instanceId, credentials) => shared.post(
|
|
55
|
+
this.ctx,
|
|
56
|
+
`/connect/v1/instances/${encodeURIComponent(instanceId)}/credentials`,
|
|
57
|
+
credentials
|
|
58
|
+
)
|
|
59
|
+
};
|
|
60
|
+
}
|
|
61
|
+
// ----------------------------------------
|
|
62
|
+
// Actions
|
|
63
|
+
// ----------------------------------------
|
|
64
|
+
/**
|
|
65
|
+
* Invoke an action on a connector instance.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```ts
|
|
69
|
+
* const result = await connect.invoke('stripe-prod', 'createCustomer', {
|
|
70
|
+
* input: { email: 'user@example.com', name: 'Test User' },
|
|
71
|
+
* dryRun: true,
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
async invoke(instanceId, action, options) {
|
|
76
|
+
const headers = {};
|
|
77
|
+
if (options?.idempotencyKey) {
|
|
78
|
+
headers["Idempotency-Key"] = options.idempotencyKey;
|
|
79
|
+
}
|
|
80
|
+
return shared.post(
|
|
81
|
+
this.ctx,
|
|
82
|
+
`/connect/v1/instances/${encodeURIComponent(instanceId)}/actions/${encodeURIComponent(action)}`,
|
|
83
|
+
{
|
|
84
|
+
input: options?.input ?? {},
|
|
85
|
+
dry_run: options?.dryRun ?? false
|
|
86
|
+
},
|
|
87
|
+
{ headers }
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
// ----------------------------------------
|
|
91
|
+
// Receivers
|
|
92
|
+
// ----------------------------------------
|
|
93
|
+
/** Manage webhook receivers. */
|
|
94
|
+
get receivers() {
|
|
95
|
+
return {
|
|
96
|
+
/** List receivers. */
|
|
97
|
+
list: async () => shared.get(this.ctx, "/connect/v1/receivers"),
|
|
98
|
+
/** Create a new receiver. */
|
|
99
|
+
create: async (options) => shared.post(this.ctx, "/connect/v1/receivers", {
|
|
100
|
+
name: options.name,
|
|
101
|
+
target: options.target,
|
|
102
|
+
filter_expression: options.filterExpression
|
|
103
|
+
}),
|
|
104
|
+
/** Get receiver details. */
|
|
105
|
+
get: async (receiverId) => shared.get(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),
|
|
106
|
+
/** Delete a receiver. */
|
|
107
|
+
delete: async (receiverId) => shared.del(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),
|
|
108
|
+
/** Rotate receiver token. */
|
|
109
|
+
rotate: async (receiverId, graceSeconds) => shared.post(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}/rotate`, {
|
|
110
|
+
grace_seconds: graceSeconds ?? 300
|
|
111
|
+
})
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
function createConnectClient(ctx) {
|
|
116
|
+
return new ConnectClient(ctx);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
exports.ConnectClient = ConnectClient;
|
|
120
|
+
exports.createConnectClient = createConnectClient;
|
|
121
|
+
//# sourceMappingURL=index.cjs.map
|
|
122
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":["get","post","patch","del"],"mappings":"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","file":"index.cjs","sourcesContent":["import {\n type RequestContext,\n type Result,\n get,\n post,\n patch,\n del,\n} from '@reactor-cloud/shared';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Connector descriptor from the catalog. */\nexport interface ConnectorDescriptor {\n type_id: string;\n display_name: string;\n version: string;\n runtime: 'native' | 'manifest' | 'airbyte_container';\n auth: AuthDescriptor;\n streams: StreamDescriptor[];\n actions: ActionDescriptor[];\n webhooks: WebhookDescriptor[];\n capabilities: ConnectorCapabilities;\n rate_limits?: RateLimitDescriptor;\n doc_url?: string;\n}\n\n/** Authentication descriptor. */\nexport interface AuthDescriptor {\n kind: AuthKind;\n fields: AuthField[];\n test?: TestCallDescriptor;\n}\n\n/** Authentication kind. */\nexport type AuthKind =\n | { kind: 'oauth2'; authorize_url: string; token_url: string; scopes: string[]; pkce?: boolean; reactor_proxy?: boolean }\n | { kind: 'personal_access_token'; header: string; format: string }\n | { kind: 'basic' }\n | { kind: 'custom'; docs_url: string };\n\n/** Authentication field. */\nexport interface AuthField {\n name: string;\n label: string;\n sensitive?: boolean;\n required?: boolean;\n description?: string;\n}\n\n/** Test call descriptor. */\nexport interface TestCallDescriptor {\n method: string;\n path: string;\n success_codes?: number[];\n}\n\n/** Stream descriptor. */\nexport interface StreamDescriptor {\n name: string;\n json_schema: Record<string, unknown>;\n supported_modes: SyncMode[];\n cursor_field?: string[];\n primary_key?: string[][];\n supports_outbound?: boolean;\n source_defined?: boolean;\n}\n\n/** Sync mode for streams. */\nexport type SyncMode = 'full_refresh' | 'incremental_append' | 'incremental_dedup';\n\n/** Action descriptor. */\nexport interface ActionDescriptor {\n name: string;\n input_schema: Record<string, unknown>;\n output_schema: Record<string, unknown>;\n side_effects: SideEffectKind;\n dry_run: DryRunSupport;\n idempotency?: IdempotencyHint;\n}\n\n/** Side effect classification. */\nexport type SideEffectKind = 'reads' | 'mutates' | 'sends';\n\n/** Dry-run support level. */\nexport type DryRunSupport = 'native' | 'synthesized' | 'unsupported';\n\n/** Idempotency hint. */\nexport interface IdempotencyHint {\n key_path: string;\n ttl_seconds: number;\n}\n\n/** Webhook descriptor. */\nexport interface WebhookDescriptor {\n name: string;\n verification: VerificationKind;\n event_types: string[];\n replay_window_seconds?: number;\n setup_instructions?: string;\n}\n\n/** Webhook verification kind. */\nexport type VerificationKind =\n | { kind: 'hmac_sha256'; header: string; secret_field: string }\n | { kind: 'ed25519'; header: string; key_id_header?: string }\n | { kind: 'custom'; docs_url: string };\n\n/** Connector capabilities. */\nexport interface ConnectorCapabilities {\n sandbox_mode?: boolean;\n vendor_test_mode?: boolean;\n cdc?: boolean;\n incremental?: boolean;\n schema_discovery?: boolean;\n}\n\n/** Rate limit descriptor. */\nexport interface RateLimitDescriptor {\n requests_per_second?: number;\n requests_per_minute?: number;\n requests_per_hour?: number;\n requests_per_day?: number;\n concurrent_requests?: number;\n}\n\n/** Connector instance. */\nexport interface Instance {\n id: string;\n connector_type: string;\n name: string;\n config: Record<string, unknown>;\n status: InstanceStatus;\n created_at: string;\n updated_at: string;\n}\n\n/** Instance status. */\nexport type InstanceStatus = 'active' | 'inactive' | 'error' | 'pending_credentials';\n\n/** Connection status. */\nexport interface ConnectionStatus {\n status: 'succeeded' | 'failed';\n message?: string;\n}\n\n/** Action result. */\nexport interface ActionResult {\n output: unknown;\n dry_run?: boolean;\n}\n\n/** Webhook receiver. */\nexport interface Receiver {\n id: string;\n name: string;\n target: ReceiverTarget;\n status: 'active' | 'inactive';\n filter_expression?: string;\n created_at: string;\n updated_at: string;\n}\n\n/** Receiver target. */\nexport type ReceiverTarget =\n | { type: 'job'; name: string }\n | { type: 'stream'; connection: string }\n | { type: 'action'; instance: string; action: string }\n | { type: 'function'; name: string };\n\n/** Receiver with token (returned on create). */\nexport interface ReceiverWithToken extends Receiver {\n token: string;\n}\n\n/** Rotate token response. */\nexport interface RotateTokenResponse {\n new_token: string;\n old_token_expires_at: string;\n}\n\n// ============================================================================\n// Options\n// ============================================================================\n\n/** Options for creating an instance. */\nexport interface CreateInstanceOptions {\n name: string;\n config?: Record<string, unknown>;\n}\n\n/** Options for updating an instance. */\nexport interface UpdateInstanceOptions {\n name?: string;\n config?: Record<string, unknown>;\n}\n\n/** Options for invoking an action. */\nexport interface InvokeActionOptions {\n input?: Record<string, unknown>;\n dryRun?: boolean;\n idempotencyKey?: string;\n}\n\n/** Options for creating a receiver. */\nexport interface CreateReceiverOptions {\n name: string;\n target: ReceiverTarget;\n filterExpression?: string;\n}\n\n/** Options for listing instances. */\nexport interface ListInstancesOptions {\n connectorType?: string;\n status?: InstanceStatus;\n limit?: number;\n offset?: number;\n}\n\n// ============================================================================\n// Client\n// ============================================================================\n\n/** Connect client for managing connectors and integrations. */\nexport class ConnectClient {\n constructor(private ctx: RequestContext) {}\n\n // ----------------------------------------\n // Catalog\n // ----------------------------------------\n\n /** Access the connector catalog. */\n get catalog() {\n return {\n /** List available connectors. */\n list: async (): Promise<Result<ConnectorDescriptor[]>> =>\n get(this.ctx, '/connect/v1/catalog'),\n\n /** Get connector details. */\n get: async (connectorType: string): Promise<Result<ConnectorDescriptor>> =>\n get(this.ctx, `/connect/v1/catalog/${encodeURIComponent(connectorType)}`),\n };\n }\n\n // ----------------------------------------\n // Instances\n // ----------------------------------------\n\n /** Manage connector instances. */\n get instances() {\n return {\n /** List instances. */\n list: async (options?: ListInstancesOptions): Promise<Result<Instance[]>> => {\n const params = new URLSearchParams();\n if (options?.connectorType) params.set('connector_type', options.connectorType);\n if (options?.status) params.set('status', options.status);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n return get(this.ctx, `/connect/v1/instances${query ? '?' + query : ''}`);\n },\n\n /** Create a new instance. */\n create: async (\n connectorType: string,\n options: CreateInstanceOptions\n ): Promise<Result<Instance>> =>\n post(this.ctx, '/connect/v1/instances', {\n connector_type: connectorType,\n name: options.name,\n config: options.config ?? {},\n }),\n\n /** Get instance details. */\n get: async (instanceId: string): Promise<Result<Instance>> =>\n get(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),\n\n /** Update an instance. */\n update: async (\n instanceId: string,\n options: UpdateInstanceOptions\n ): Promise<Result<Instance>> =>\n patch(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`, options),\n\n /** Delete an instance. */\n delete: async (instanceId: string): Promise<Result<void>> =>\n del(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),\n\n /** Test instance credentials. */\n check: async (instanceId: string): Promise<Result<ConnectionStatus>> =>\n post(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}/check`, {}),\n\n /** Set credentials for an instance. */\n setCredentials: async (\n instanceId: string,\n credentials: Record<string, unknown>\n ): Promise<Result<void>> =>\n post(\n this.ctx,\n `/connect/v1/instances/${encodeURIComponent(instanceId)}/credentials`,\n credentials\n ),\n };\n }\n\n // ----------------------------------------\n // Actions\n // ----------------------------------------\n\n /**\n * Invoke an action on a connector instance.\n *\n * @example\n * ```ts\n * const result = await connect.invoke('stripe-prod', 'createCustomer', {\n * input: { email: 'user@example.com', name: 'Test User' },\n * dryRun: true,\n * });\n * ```\n */\n async invoke(\n instanceId: string,\n action: string,\n options?: InvokeActionOptions\n ): Promise<Result<ActionResult>> {\n const headers: Record<string, string> = {};\n if (options?.idempotencyKey) {\n headers['Idempotency-Key'] = options.idempotencyKey;\n }\n\n return post(\n this.ctx,\n `/connect/v1/instances/${encodeURIComponent(instanceId)}/actions/${encodeURIComponent(action)}`,\n {\n input: options?.input ?? {},\n dry_run: options?.dryRun ?? false,\n },\n { headers }\n );\n }\n\n // ----------------------------------------\n // Receivers\n // ----------------------------------------\n\n /** Manage webhook receivers. */\n get receivers() {\n return {\n /** List receivers. */\n list: async (): Promise<Result<Receiver[]>> =>\n get(this.ctx, '/connect/v1/receivers'),\n\n /** Create a new receiver. */\n create: async (options: CreateReceiverOptions): Promise<Result<ReceiverWithToken>> =>\n post(this.ctx, '/connect/v1/receivers', {\n name: options.name,\n target: options.target,\n filter_expression: options.filterExpression,\n }),\n\n /** Get receiver details. */\n get: async (receiverId: string): Promise<Result<Receiver>> =>\n get(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),\n\n /** Delete a receiver. */\n delete: async (receiverId: string): Promise<Result<void>> =>\n del(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),\n\n /** Rotate receiver token. */\n rotate: async (\n receiverId: string,\n graceSeconds?: number\n ): Promise<Result<RotateTokenResponse>> =>\n post(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}/rotate`, {\n grace_seconds: graceSeconds ?? 300,\n }),\n };\n }\n}\n\n/**\n * Create a Connect client.\n *\n * @example\n * ```ts\n * import { createClient } from '@reactor-cloud/client';\n * import { createConnectClient } from '@reactor-cloud/connect';\n *\n * const reactor = createClient({ endpoint: 'https://api.example.com' });\n * const connect = createConnectClient(reactor.context);\n *\n * // List available connectors\n * const { data: connectors } = await connect.catalog.list();\n *\n * // Create a Stripe instance\n * const { data: instance } = await connect.instances.create('stripe', {\n * name: 'stripe-prod',\n * config: { api_key: 'sk_test_...' },\n * });\n *\n * // Invoke an action\n * const { data: result } = await connect.invoke(instance.id, 'createCustomer', {\n * input: { email: 'user@example.com' },\n * dryRun: true,\n * });\n * ```\n */\nexport function createConnectClient(ctx: RequestContext): ConnectClient {\n return new ConnectClient(ctx);\n}\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { RequestContext, Result } from '@reactor-cloud/shared';
|
|
2
|
+
|
|
3
|
+
/** Connector descriptor from the catalog. */
|
|
4
|
+
interface ConnectorDescriptor {
|
|
5
|
+
type_id: string;
|
|
6
|
+
display_name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
runtime: 'native' | 'manifest' | 'airbyte_container';
|
|
9
|
+
auth: AuthDescriptor;
|
|
10
|
+
streams: StreamDescriptor[];
|
|
11
|
+
actions: ActionDescriptor[];
|
|
12
|
+
webhooks: WebhookDescriptor[];
|
|
13
|
+
capabilities: ConnectorCapabilities;
|
|
14
|
+
rate_limits?: RateLimitDescriptor;
|
|
15
|
+
doc_url?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Authentication descriptor. */
|
|
18
|
+
interface AuthDescriptor {
|
|
19
|
+
kind: AuthKind;
|
|
20
|
+
fields: AuthField[];
|
|
21
|
+
test?: TestCallDescriptor;
|
|
22
|
+
}
|
|
23
|
+
/** Authentication kind. */
|
|
24
|
+
type AuthKind = {
|
|
25
|
+
kind: 'oauth2';
|
|
26
|
+
authorize_url: string;
|
|
27
|
+
token_url: string;
|
|
28
|
+
scopes: string[];
|
|
29
|
+
pkce?: boolean;
|
|
30
|
+
reactor_proxy?: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'personal_access_token';
|
|
33
|
+
header: string;
|
|
34
|
+
format: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'basic';
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'custom';
|
|
39
|
+
docs_url: string;
|
|
40
|
+
};
|
|
41
|
+
/** Authentication field. */
|
|
42
|
+
interface AuthField {
|
|
43
|
+
name: string;
|
|
44
|
+
label: string;
|
|
45
|
+
sensitive?: boolean;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
description?: string;
|
|
48
|
+
}
|
|
49
|
+
/** Test call descriptor. */
|
|
50
|
+
interface TestCallDescriptor {
|
|
51
|
+
method: string;
|
|
52
|
+
path: string;
|
|
53
|
+
success_codes?: number[];
|
|
54
|
+
}
|
|
55
|
+
/** Stream descriptor. */
|
|
56
|
+
interface StreamDescriptor {
|
|
57
|
+
name: string;
|
|
58
|
+
json_schema: Record<string, unknown>;
|
|
59
|
+
supported_modes: SyncMode[];
|
|
60
|
+
cursor_field?: string[];
|
|
61
|
+
primary_key?: string[][];
|
|
62
|
+
supports_outbound?: boolean;
|
|
63
|
+
source_defined?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Sync mode for streams. */
|
|
66
|
+
type SyncMode = 'full_refresh' | 'incremental_append' | 'incremental_dedup';
|
|
67
|
+
/** Action descriptor. */
|
|
68
|
+
interface ActionDescriptor {
|
|
69
|
+
name: string;
|
|
70
|
+
input_schema: Record<string, unknown>;
|
|
71
|
+
output_schema: Record<string, unknown>;
|
|
72
|
+
side_effects: SideEffectKind;
|
|
73
|
+
dry_run: DryRunSupport;
|
|
74
|
+
idempotency?: IdempotencyHint;
|
|
75
|
+
}
|
|
76
|
+
/** Side effect classification. */
|
|
77
|
+
type SideEffectKind = 'reads' | 'mutates' | 'sends';
|
|
78
|
+
/** Dry-run support level. */
|
|
79
|
+
type DryRunSupport = 'native' | 'synthesized' | 'unsupported';
|
|
80
|
+
/** Idempotency hint. */
|
|
81
|
+
interface IdempotencyHint {
|
|
82
|
+
key_path: string;
|
|
83
|
+
ttl_seconds: number;
|
|
84
|
+
}
|
|
85
|
+
/** Webhook descriptor. */
|
|
86
|
+
interface WebhookDescriptor {
|
|
87
|
+
name: string;
|
|
88
|
+
verification: VerificationKind;
|
|
89
|
+
event_types: string[];
|
|
90
|
+
replay_window_seconds?: number;
|
|
91
|
+
setup_instructions?: string;
|
|
92
|
+
}
|
|
93
|
+
/** Webhook verification kind. */
|
|
94
|
+
type VerificationKind = {
|
|
95
|
+
kind: 'hmac_sha256';
|
|
96
|
+
header: string;
|
|
97
|
+
secret_field: string;
|
|
98
|
+
} | {
|
|
99
|
+
kind: 'ed25519';
|
|
100
|
+
header: string;
|
|
101
|
+
key_id_header?: string;
|
|
102
|
+
} | {
|
|
103
|
+
kind: 'custom';
|
|
104
|
+
docs_url: string;
|
|
105
|
+
};
|
|
106
|
+
/** Connector capabilities. */
|
|
107
|
+
interface ConnectorCapabilities {
|
|
108
|
+
sandbox_mode?: boolean;
|
|
109
|
+
vendor_test_mode?: boolean;
|
|
110
|
+
cdc?: boolean;
|
|
111
|
+
incremental?: boolean;
|
|
112
|
+
schema_discovery?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/** Rate limit descriptor. */
|
|
115
|
+
interface RateLimitDescriptor {
|
|
116
|
+
requests_per_second?: number;
|
|
117
|
+
requests_per_minute?: number;
|
|
118
|
+
requests_per_hour?: number;
|
|
119
|
+
requests_per_day?: number;
|
|
120
|
+
concurrent_requests?: number;
|
|
121
|
+
}
|
|
122
|
+
/** Connector instance. */
|
|
123
|
+
interface Instance {
|
|
124
|
+
id: string;
|
|
125
|
+
connector_type: string;
|
|
126
|
+
name: string;
|
|
127
|
+
config: Record<string, unknown>;
|
|
128
|
+
status: InstanceStatus;
|
|
129
|
+
created_at: string;
|
|
130
|
+
updated_at: string;
|
|
131
|
+
}
|
|
132
|
+
/** Instance status. */
|
|
133
|
+
type InstanceStatus = 'active' | 'inactive' | 'error' | 'pending_credentials';
|
|
134
|
+
/** Connection status. */
|
|
135
|
+
interface ConnectionStatus {
|
|
136
|
+
status: 'succeeded' | 'failed';
|
|
137
|
+
message?: string;
|
|
138
|
+
}
|
|
139
|
+
/** Action result. */
|
|
140
|
+
interface ActionResult {
|
|
141
|
+
output: unknown;
|
|
142
|
+
dry_run?: boolean;
|
|
143
|
+
}
|
|
144
|
+
/** Webhook receiver. */
|
|
145
|
+
interface Receiver {
|
|
146
|
+
id: string;
|
|
147
|
+
name: string;
|
|
148
|
+
target: ReceiverTarget;
|
|
149
|
+
status: 'active' | 'inactive';
|
|
150
|
+
filter_expression?: string;
|
|
151
|
+
created_at: string;
|
|
152
|
+
updated_at: string;
|
|
153
|
+
}
|
|
154
|
+
/** Receiver target. */
|
|
155
|
+
type ReceiverTarget = {
|
|
156
|
+
type: 'job';
|
|
157
|
+
name: string;
|
|
158
|
+
} | {
|
|
159
|
+
type: 'stream';
|
|
160
|
+
connection: string;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'action';
|
|
163
|
+
instance: string;
|
|
164
|
+
action: string;
|
|
165
|
+
} | {
|
|
166
|
+
type: 'function';
|
|
167
|
+
name: string;
|
|
168
|
+
};
|
|
169
|
+
/** Receiver with token (returned on create). */
|
|
170
|
+
interface ReceiverWithToken extends Receiver {
|
|
171
|
+
token: string;
|
|
172
|
+
}
|
|
173
|
+
/** Rotate token response. */
|
|
174
|
+
interface RotateTokenResponse {
|
|
175
|
+
new_token: string;
|
|
176
|
+
old_token_expires_at: string;
|
|
177
|
+
}
|
|
178
|
+
/** Options for creating an instance. */
|
|
179
|
+
interface CreateInstanceOptions {
|
|
180
|
+
name: string;
|
|
181
|
+
config?: Record<string, unknown>;
|
|
182
|
+
}
|
|
183
|
+
/** Options for updating an instance. */
|
|
184
|
+
interface UpdateInstanceOptions {
|
|
185
|
+
name?: string;
|
|
186
|
+
config?: Record<string, unknown>;
|
|
187
|
+
}
|
|
188
|
+
/** Options for invoking an action. */
|
|
189
|
+
interface InvokeActionOptions {
|
|
190
|
+
input?: Record<string, unknown>;
|
|
191
|
+
dryRun?: boolean;
|
|
192
|
+
idempotencyKey?: string;
|
|
193
|
+
}
|
|
194
|
+
/** Options for creating a receiver. */
|
|
195
|
+
interface CreateReceiverOptions {
|
|
196
|
+
name: string;
|
|
197
|
+
target: ReceiverTarget;
|
|
198
|
+
filterExpression?: string;
|
|
199
|
+
}
|
|
200
|
+
/** Options for listing instances. */
|
|
201
|
+
interface ListInstancesOptions {
|
|
202
|
+
connectorType?: string;
|
|
203
|
+
status?: InstanceStatus;
|
|
204
|
+
limit?: number;
|
|
205
|
+
offset?: number;
|
|
206
|
+
}
|
|
207
|
+
/** Connect client for managing connectors and integrations. */
|
|
208
|
+
declare class ConnectClient {
|
|
209
|
+
private ctx;
|
|
210
|
+
constructor(ctx: RequestContext);
|
|
211
|
+
/** Access the connector catalog. */
|
|
212
|
+
get catalog(): {
|
|
213
|
+
/** List available connectors. */
|
|
214
|
+
list: () => Promise<Result<ConnectorDescriptor[]>>;
|
|
215
|
+
/** Get connector details. */
|
|
216
|
+
get: (connectorType: string) => Promise<Result<ConnectorDescriptor>>;
|
|
217
|
+
};
|
|
218
|
+
/** Manage connector instances. */
|
|
219
|
+
get instances(): {
|
|
220
|
+
/** List instances. */
|
|
221
|
+
list: (options?: ListInstancesOptions) => Promise<Result<Instance[]>>;
|
|
222
|
+
/** Create a new instance. */
|
|
223
|
+
create: (connectorType: string, options: CreateInstanceOptions) => Promise<Result<Instance>>;
|
|
224
|
+
/** Get instance details. */
|
|
225
|
+
get: (instanceId: string) => Promise<Result<Instance>>;
|
|
226
|
+
/** Update an instance. */
|
|
227
|
+
update: (instanceId: string, options: UpdateInstanceOptions) => Promise<Result<Instance>>;
|
|
228
|
+
/** Delete an instance. */
|
|
229
|
+
delete: (instanceId: string) => Promise<Result<void>>;
|
|
230
|
+
/** Test instance credentials. */
|
|
231
|
+
check: (instanceId: string) => Promise<Result<ConnectionStatus>>;
|
|
232
|
+
/** Set credentials for an instance. */
|
|
233
|
+
setCredentials: (instanceId: string, credentials: Record<string, unknown>) => Promise<Result<void>>;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Invoke an action on a connector instance.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* const result = await connect.invoke('stripe-prod', 'createCustomer', {
|
|
241
|
+
* input: { email: 'user@example.com', name: 'Test User' },
|
|
242
|
+
* dryRun: true,
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
invoke(instanceId: string, action: string, options?: InvokeActionOptions): Promise<Result<ActionResult>>;
|
|
247
|
+
/** Manage webhook receivers. */
|
|
248
|
+
get receivers(): {
|
|
249
|
+
/** List receivers. */
|
|
250
|
+
list: () => Promise<Result<Receiver[]>>;
|
|
251
|
+
/** Create a new receiver. */
|
|
252
|
+
create: (options: CreateReceiverOptions) => Promise<Result<ReceiverWithToken>>;
|
|
253
|
+
/** Get receiver details. */
|
|
254
|
+
get: (receiverId: string) => Promise<Result<Receiver>>;
|
|
255
|
+
/** Delete a receiver. */
|
|
256
|
+
delete: (receiverId: string) => Promise<Result<void>>;
|
|
257
|
+
/** Rotate receiver token. */
|
|
258
|
+
rotate: (receiverId: string, graceSeconds?: number) => Promise<Result<RotateTokenResponse>>;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Create a Connect client.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { createClient } from '@reactor-cloud/client';
|
|
267
|
+
* import { createConnectClient } from '@reactor-cloud/connect';
|
|
268
|
+
*
|
|
269
|
+
* const reactor = createClient({ endpoint: 'https://api.example.com' });
|
|
270
|
+
* const connect = createConnectClient(reactor.context);
|
|
271
|
+
*
|
|
272
|
+
* // List available connectors
|
|
273
|
+
* const { data: connectors } = await connect.catalog.list();
|
|
274
|
+
*
|
|
275
|
+
* // Create a Stripe instance
|
|
276
|
+
* const { data: instance } = await connect.instances.create('stripe', {
|
|
277
|
+
* name: 'stripe-prod',
|
|
278
|
+
* config: { api_key: 'sk_test_...' },
|
|
279
|
+
* });
|
|
280
|
+
*
|
|
281
|
+
* // Invoke an action
|
|
282
|
+
* const { data: result } = await connect.invoke(instance.id, 'createCustomer', {
|
|
283
|
+
* input: { email: 'user@example.com' },
|
|
284
|
+
* dryRun: true,
|
|
285
|
+
* });
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
declare function createConnectClient(ctx: RequestContext): ConnectClient;
|
|
289
|
+
|
|
290
|
+
export { type ActionDescriptor, type ActionResult, type AuthDescriptor, type AuthField, type AuthKind, ConnectClient, type ConnectionStatus, type ConnectorCapabilities, type ConnectorDescriptor, type CreateInstanceOptions, type CreateReceiverOptions, type DryRunSupport, type IdempotencyHint, type Instance, type InstanceStatus, type InvokeActionOptions, type ListInstancesOptions, type RateLimitDescriptor, type Receiver, type ReceiverTarget, type ReceiverWithToken, type RotateTokenResponse, type SideEffectKind, type StreamDescriptor, type SyncMode, type TestCallDescriptor, type UpdateInstanceOptions, type VerificationKind, type WebhookDescriptor, createConnectClient };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,290 @@
|
|
|
1
|
+
import { RequestContext, Result } from '@reactor-cloud/shared';
|
|
2
|
+
|
|
3
|
+
/** Connector descriptor from the catalog. */
|
|
4
|
+
interface ConnectorDescriptor {
|
|
5
|
+
type_id: string;
|
|
6
|
+
display_name: string;
|
|
7
|
+
version: string;
|
|
8
|
+
runtime: 'native' | 'manifest' | 'airbyte_container';
|
|
9
|
+
auth: AuthDescriptor;
|
|
10
|
+
streams: StreamDescriptor[];
|
|
11
|
+
actions: ActionDescriptor[];
|
|
12
|
+
webhooks: WebhookDescriptor[];
|
|
13
|
+
capabilities: ConnectorCapabilities;
|
|
14
|
+
rate_limits?: RateLimitDescriptor;
|
|
15
|
+
doc_url?: string;
|
|
16
|
+
}
|
|
17
|
+
/** Authentication descriptor. */
|
|
18
|
+
interface AuthDescriptor {
|
|
19
|
+
kind: AuthKind;
|
|
20
|
+
fields: AuthField[];
|
|
21
|
+
test?: TestCallDescriptor;
|
|
22
|
+
}
|
|
23
|
+
/** Authentication kind. */
|
|
24
|
+
type AuthKind = {
|
|
25
|
+
kind: 'oauth2';
|
|
26
|
+
authorize_url: string;
|
|
27
|
+
token_url: string;
|
|
28
|
+
scopes: string[];
|
|
29
|
+
pkce?: boolean;
|
|
30
|
+
reactor_proxy?: boolean;
|
|
31
|
+
} | {
|
|
32
|
+
kind: 'personal_access_token';
|
|
33
|
+
header: string;
|
|
34
|
+
format: string;
|
|
35
|
+
} | {
|
|
36
|
+
kind: 'basic';
|
|
37
|
+
} | {
|
|
38
|
+
kind: 'custom';
|
|
39
|
+
docs_url: string;
|
|
40
|
+
};
|
|
41
|
+
/** Authentication field. */
|
|
42
|
+
interface AuthField {
|
|
43
|
+
name: string;
|
|
44
|
+
label: string;
|
|
45
|
+
sensitive?: boolean;
|
|
46
|
+
required?: boolean;
|
|
47
|
+
description?: string;
|
|
48
|
+
}
|
|
49
|
+
/** Test call descriptor. */
|
|
50
|
+
interface TestCallDescriptor {
|
|
51
|
+
method: string;
|
|
52
|
+
path: string;
|
|
53
|
+
success_codes?: number[];
|
|
54
|
+
}
|
|
55
|
+
/** Stream descriptor. */
|
|
56
|
+
interface StreamDescriptor {
|
|
57
|
+
name: string;
|
|
58
|
+
json_schema: Record<string, unknown>;
|
|
59
|
+
supported_modes: SyncMode[];
|
|
60
|
+
cursor_field?: string[];
|
|
61
|
+
primary_key?: string[][];
|
|
62
|
+
supports_outbound?: boolean;
|
|
63
|
+
source_defined?: boolean;
|
|
64
|
+
}
|
|
65
|
+
/** Sync mode for streams. */
|
|
66
|
+
type SyncMode = 'full_refresh' | 'incremental_append' | 'incremental_dedup';
|
|
67
|
+
/** Action descriptor. */
|
|
68
|
+
interface ActionDescriptor {
|
|
69
|
+
name: string;
|
|
70
|
+
input_schema: Record<string, unknown>;
|
|
71
|
+
output_schema: Record<string, unknown>;
|
|
72
|
+
side_effects: SideEffectKind;
|
|
73
|
+
dry_run: DryRunSupport;
|
|
74
|
+
idempotency?: IdempotencyHint;
|
|
75
|
+
}
|
|
76
|
+
/** Side effect classification. */
|
|
77
|
+
type SideEffectKind = 'reads' | 'mutates' | 'sends';
|
|
78
|
+
/** Dry-run support level. */
|
|
79
|
+
type DryRunSupport = 'native' | 'synthesized' | 'unsupported';
|
|
80
|
+
/** Idempotency hint. */
|
|
81
|
+
interface IdempotencyHint {
|
|
82
|
+
key_path: string;
|
|
83
|
+
ttl_seconds: number;
|
|
84
|
+
}
|
|
85
|
+
/** Webhook descriptor. */
|
|
86
|
+
interface WebhookDescriptor {
|
|
87
|
+
name: string;
|
|
88
|
+
verification: VerificationKind;
|
|
89
|
+
event_types: string[];
|
|
90
|
+
replay_window_seconds?: number;
|
|
91
|
+
setup_instructions?: string;
|
|
92
|
+
}
|
|
93
|
+
/** Webhook verification kind. */
|
|
94
|
+
type VerificationKind = {
|
|
95
|
+
kind: 'hmac_sha256';
|
|
96
|
+
header: string;
|
|
97
|
+
secret_field: string;
|
|
98
|
+
} | {
|
|
99
|
+
kind: 'ed25519';
|
|
100
|
+
header: string;
|
|
101
|
+
key_id_header?: string;
|
|
102
|
+
} | {
|
|
103
|
+
kind: 'custom';
|
|
104
|
+
docs_url: string;
|
|
105
|
+
};
|
|
106
|
+
/** Connector capabilities. */
|
|
107
|
+
interface ConnectorCapabilities {
|
|
108
|
+
sandbox_mode?: boolean;
|
|
109
|
+
vendor_test_mode?: boolean;
|
|
110
|
+
cdc?: boolean;
|
|
111
|
+
incremental?: boolean;
|
|
112
|
+
schema_discovery?: boolean;
|
|
113
|
+
}
|
|
114
|
+
/** Rate limit descriptor. */
|
|
115
|
+
interface RateLimitDescriptor {
|
|
116
|
+
requests_per_second?: number;
|
|
117
|
+
requests_per_minute?: number;
|
|
118
|
+
requests_per_hour?: number;
|
|
119
|
+
requests_per_day?: number;
|
|
120
|
+
concurrent_requests?: number;
|
|
121
|
+
}
|
|
122
|
+
/** Connector instance. */
|
|
123
|
+
interface Instance {
|
|
124
|
+
id: string;
|
|
125
|
+
connector_type: string;
|
|
126
|
+
name: string;
|
|
127
|
+
config: Record<string, unknown>;
|
|
128
|
+
status: InstanceStatus;
|
|
129
|
+
created_at: string;
|
|
130
|
+
updated_at: string;
|
|
131
|
+
}
|
|
132
|
+
/** Instance status. */
|
|
133
|
+
type InstanceStatus = 'active' | 'inactive' | 'error' | 'pending_credentials';
|
|
134
|
+
/** Connection status. */
|
|
135
|
+
interface ConnectionStatus {
|
|
136
|
+
status: 'succeeded' | 'failed';
|
|
137
|
+
message?: string;
|
|
138
|
+
}
|
|
139
|
+
/** Action result. */
|
|
140
|
+
interface ActionResult {
|
|
141
|
+
output: unknown;
|
|
142
|
+
dry_run?: boolean;
|
|
143
|
+
}
|
|
144
|
+
/** Webhook receiver. */
|
|
145
|
+
interface Receiver {
|
|
146
|
+
id: string;
|
|
147
|
+
name: string;
|
|
148
|
+
target: ReceiverTarget;
|
|
149
|
+
status: 'active' | 'inactive';
|
|
150
|
+
filter_expression?: string;
|
|
151
|
+
created_at: string;
|
|
152
|
+
updated_at: string;
|
|
153
|
+
}
|
|
154
|
+
/** Receiver target. */
|
|
155
|
+
type ReceiverTarget = {
|
|
156
|
+
type: 'job';
|
|
157
|
+
name: string;
|
|
158
|
+
} | {
|
|
159
|
+
type: 'stream';
|
|
160
|
+
connection: string;
|
|
161
|
+
} | {
|
|
162
|
+
type: 'action';
|
|
163
|
+
instance: string;
|
|
164
|
+
action: string;
|
|
165
|
+
} | {
|
|
166
|
+
type: 'function';
|
|
167
|
+
name: string;
|
|
168
|
+
};
|
|
169
|
+
/** Receiver with token (returned on create). */
|
|
170
|
+
interface ReceiverWithToken extends Receiver {
|
|
171
|
+
token: string;
|
|
172
|
+
}
|
|
173
|
+
/** Rotate token response. */
|
|
174
|
+
interface RotateTokenResponse {
|
|
175
|
+
new_token: string;
|
|
176
|
+
old_token_expires_at: string;
|
|
177
|
+
}
|
|
178
|
+
/** Options for creating an instance. */
|
|
179
|
+
interface CreateInstanceOptions {
|
|
180
|
+
name: string;
|
|
181
|
+
config?: Record<string, unknown>;
|
|
182
|
+
}
|
|
183
|
+
/** Options for updating an instance. */
|
|
184
|
+
interface UpdateInstanceOptions {
|
|
185
|
+
name?: string;
|
|
186
|
+
config?: Record<string, unknown>;
|
|
187
|
+
}
|
|
188
|
+
/** Options for invoking an action. */
|
|
189
|
+
interface InvokeActionOptions {
|
|
190
|
+
input?: Record<string, unknown>;
|
|
191
|
+
dryRun?: boolean;
|
|
192
|
+
idempotencyKey?: string;
|
|
193
|
+
}
|
|
194
|
+
/** Options for creating a receiver. */
|
|
195
|
+
interface CreateReceiverOptions {
|
|
196
|
+
name: string;
|
|
197
|
+
target: ReceiverTarget;
|
|
198
|
+
filterExpression?: string;
|
|
199
|
+
}
|
|
200
|
+
/** Options for listing instances. */
|
|
201
|
+
interface ListInstancesOptions {
|
|
202
|
+
connectorType?: string;
|
|
203
|
+
status?: InstanceStatus;
|
|
204
|
+
limit?: number;
|
|
205
|
+
offset?: number;
|
|
206
|
+
}
|
|
207
|
+
/** Connect client for managing connectors and integrations. */
|
|
208
|
+
declare class ConnectClient {
|
|
209
|
+
private ctx;
|
|
210
|
+
constructor(ctx: RequestContext);
|
|
211
|
+
/** Access the connector catalog. */
|
|
212
|
+
get catalog(): {
|
|
213
|
+
/** List available connectors. */
|
|
214
|
+
list: () => Promise<Result<ConnectorDescriptor[]>>;
|
|
215
|
+
/** Get connector details. */
|
|
216
|
+
get: (connectorType: string) => Promise<Result<ConnectorDescriptor>>;
|
|
217
|
+
};
|
|
218
|
+
/** Manage connector instances. */
|
|
219
|
+
get instances(): {
|
|
220
|
+
/** List instances. */
|
|
221
|
+
list: (options?: ListInstancesOptions) => Promise<Result<Instance[]>>;
|
|
222
|
+
/** Create a new instance. */
|
|
223
|
+
create: (connectorType: string, options: CreateInstanceOptions) => Promise<Result<Instance>>;
|
|
224
|
+
/** Get instance details. */
|
|
225
|
+
get: (instanceId: string) => Promise<Result<Instance>>;
|
|
226
|
+
/** Update an instance. */
|
|
227
|
+
update: (instanceId: string, options: UpdateInstanceOptions) => Promise<Result<Instance>>;
|
|
228
|
+
/** Delete an instance. */
|
|
229
|
+
delete: (instanceId: string) => Promise<Result<void>>;
|
|
230
|
+
/** Test instance credentials. */
|
|
231
|
+
check: (instanceId: string) => Promise<Result<ConnectionStatus>>;
|
|
232
|
+
/** Set credentials for an instance. */
|
|
233
|
+
setCredentials: (instanceId: string, credentials: Record<string, unknown>) => Promise<Result<void>>;
|
|
234
|
+
};
|
|
235
|
+
/**
|
|
236
|
+
* Invoke an action on a connector instance.
|
|
237
|
+
*
|
|
238
|
+
* @example
|
|
239
|
+
* ```ts
|
|
240
|
+
* const result = await connect.invoke('stripe-prod', 'createCustomer', {
|
|
241
|
+
* input: { email: 'user@example.com', name: 'Test User' },
|
|
242
|
+
* dryRun: true,
|
|
243
|
+
* });
|
|
244
|
+
* ```
|
|
245
|
+
*/
|
|
246
|
+
invoke(instanceId: string, action: string, options?: InvokeActionOptions): Promise<Result<ActionResult>>;
|
|
247
|
+
/** Manage webhook receivers. */
|
|
248
|
+
get receivers(): {
|
|
249
|
+
/** List receivers. */
|
|
250
|
+
list: () => Promise<Result<Receiver[]>>;
|
|
251
|
+
/** Create a new receiver. */
|
|
252
|
+
create: (options: CreateReceiverOptions) => Promise<Result<ReceiverWithToken>>;
|
|
253
|
+
/** Get receiver details. */
|
|
254
|
+
get: (receiverId: string) => Promise<Result<Receiver>>;
|
|
255
|
+
/** Delete a receiver. */
|
|
256
|
+
delete: (receiverId: string) => Promise<Result<void>>;
|
|
257
|
+
/** Rotate receiver token. */
|
|
258
|
+
rotate: (receiverId: string, graceSeconds?: number) => Promise<Result<RotateTokenResponse>>;
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Create a Connect client.
|
|
263
|
+
*
|
|
264
|
+
* @example
|
|
265
|
+
* ```ts
|
|
266
|
+
* import { createClient } from '@reactor-cloud/client';
|
|
267
|
+
* import { createConnectClient } from '@reactor-cloud/connect';
|
|
268
|
+
*
|
|
269
|
+
* const reactor = createClient({ endpoint: 'https://api.example.com' });
|
|
270
|
+
* const connect = createConnectClient(reactor.context);
|
|
271
|
+
*
|
|
272
|
+
* // List available connectors
|
|
273
|
+
* const { data: connectors } = await connect.catalog.list();
|
|
274
|
+
*
|
|
275
|
+
* // Create a Stripe instance
|
|
276
|
+
* const { data: instance } = await connect.instances.create('stripe', {
|
|
277
|
+
* name: 'stripe-prod',
|
|
278
|
+
* config: { api_key: 'sk_test_...' },
|
|
279
|
+
* });
|
|
280
|
+
*
|
|
281
|
+
* // Invoke an action
|
|
282
|
+
* const { data: result } = await connect.invoke(instance.id, 'createCustomer', {
|
|
283
|
+
* input: { email: 'user@example.com' },
|
|
284
|
+
* dryRun: true,
|
|
285
|
+
* });
|
|
286
|
+
* ```
|
|
287
|
+
*/
|
|
288
|
+
declare function createConnectClient(ctx: RequestContext): ConnectClient;
|
|
289
|
+
|
|
290
|
+
export { type ActionDescriptor, type ActionResult, type AuthDescriptor, type AuthField, type AuthKind, ConnectClient, type ConnectionStatus, type ConnectorCapabilities, type ConnectorDescriptor, type CreateInstanceOptions, type CreateReceiverOptions, type DryRunSupport, type IdempotencyHint, type Instance, type InstanceStatus, type InvokeActionOptions, type ListInstancesOptions, type RateLimitDescriptor, type Receiver, type ReceiverTarget, type ReceiverWithToken, type RotateTokenResponse, type SideEffectKind, type StreamDescriptor, type SyncMode, type TestCallDescriptor, type UpdateInstanceOptions, type VerificationKind, type WebhookDescriptor, createConnectClient };
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import { get, post, del, patch } from '@reactor-cloud/shared';
|
|
2
|
+
|
|
3
|
+
// src/index.ts
|
|
4
|
+
var ConnectClient = class {
|
|
5
|
+
constructor(ctx) {
|
|
6
|
+
this.ctx = ctx;
|
|
7
|
+
}
|
|
8
|
+
ctx;
|
|
9
|
+
// ----------------------------------------
|
|
10
|
+
// Catalog
|
|
11
|
+
// ----------------------------------------
|
|
12
|
+
/** Access the connector catalog. */
|
|
13
|
+
get catalog() {
|
|
14
|
+
return {
|
|
15
|
+
/** List available connectors. */
|
|
16
|
+
list: async () => get(this.ctx, "/connect/v1/catalog"),
|
|
17
|
+
/** Get connector details. */
|
|
18
|
+
get: async (connectorType) => get(this.ctx, `/connect/v1/catalog/${encodeURIComponent(connectorType)}`)
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
// ----------------------------------------
|
|
22
|
+
// Instances
|
|
23
|
+
// ----------------------------------------
|
|
24
|
+
/** Manage connector instances. */
|
|
25
|
+
get instances() {
|
|
26
|
+
return {
|
|
27
|
+
/** List instances. */
|
|
28
|
+
list: async (options) => {
|
|
29
|
+
const params = new URLSearchParams();
|
|
30
|
+
if (options?.connectorType) params.set("connector_type", options.connectorType);
|
|
31
|
+
if (options?.status) params.set("status", options.status);
|
|
32
|
+
if (options?.limit) params.set("limit", String(options.limit));
|
|
33
|
+
if (options?.offset) params.set("offset", String(options.offset));
|
|
34
|
+
const query = params.toString();
|
|
35
|
+
return get(this.ctx, `/connect/v1/instances${query ? "?" + query : ""}`);
|
|
36
|
+
},
|
|
37
|
+
/** Create a new instance. */
|
|
38
|
+
create: async (connectorType, options) => post(this.ctx, "/connect/v1/instances", {
|
|
39
|
+
connector_type: connectorType,
|
|
40
|
+
name: options.name,
|
|
41
|
+
config: options.config ?? {}
|
|
42
|
+
}),
|
|
43
|
+
/** Get instance details. */
|
|
44
|
+
get: async (instanceId) => get(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),
|
|
45
|
+
/** Update an instance. */
|
|
46
|
+
update: async (instanceId, options) => patch(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`, options),
|
|
47
|
+
/** Delete an instance. */
|
|
48
|
+
delete: async (instanceId) => del(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),
|
|
49
|
+
/** Test instance credentials. */
|
|
50
|
+
check: async (instanceId) => post(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}/check`, {}),
|
|
51
|
+
/** Set credentials for an instance. */
|
|
52
|
+
setCredentials: async (instanceId, credentials) => post(
|
|
53
|
+
this.ctx,
|
|
54
|
+
`/connect/v1/instances/${encodeURIComponent(instanceId)}/credentials`,
|
|
55
|
+
credentials
|
|
56
|
+
)
|
|
57
|
+
};
|
|
58
|
+
}
|
|
59
|
+
// ----------------------------------------
|
|
60
|
+
// Actions
|
|
61
|
+
// ----------------------------------------
|
|
62
|
+
/**
|
|
63
|
+
* Invoke an action on a connector instance.
|
|
64
|
+
*
|
|
65
|
+
* @example
|
|
66
|
+
* ```ts
|
|
67
|
+
* const result = await connect.invoke('stripe-prod', 'createCustomer', {
|
|
68
|
+
* input: { email: 'user@example.com', name: 'Test User' },
|
|
69
|
+
* dryRun: true,
|
|
70
|
+
* });
|
|
71
|
+
* ```
|
|
72
|
+
*/
|
|
73
|
+
async invoke(instanceId, action, options) {
|
|
74
|
+
const headers = {};
|
|
75
|
+
if (options?.idempotencyKey) {
|
|
76
|
+
headers["Idempotency-Key"] = options.idempotencyKey;
|
|
77
|
+
}
|
|
78
|
+
return post(
|
|
79
|
+
this.ctx,
|
|
80
|
+
`/connect/v1/instances/${encodeURIComponent(instanceId)}/actions/${encodeURIComponent(action)}`,
|
|
81
|
+
{
|
|
82
|
+
input: options?.input ?? {},
|
|
83
|
+
dry_run: options?.dryRun ?? false
|
|
84
|
+
},
|
|
85
|
+
{ headers }
|
|
86
|
+
);
|
|
87
|
+
}
|
|
88
|
+
// ----------------------------------------
|
|
89
|
+
// Receivers
|
|
90
|
+
// ----------------------------------------
|
|
91
|
+
/** Manage webhook receivers. */
|
|
92
|
+
get receivers() {
|
|
93
|
+
return {
|
|
94
|
+
/** List receivers. */
|
|
95
|
+
list: async () => get(this.ctx, "/connect/v1/receivers"),
|
|
96
|
+
/** Create a new receiver. */
|
|
97
|
+
create: async (options) => post(this.ctx, "/connect/v1/receivers", {
|
|
98
|
+
name: options.name,
|
|
99
|
+
target: options.target,
|
|
100
|
+
filter_expression: options.filterExpression
|
|
101
|
+
}),
|
|
102
|
+
/** Get receiver details. */
|
|
103
|
+
get: async (receiverId) => get(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),
|
|
104
|
+
/** Delete a receiver. */
|
|
105
|
+
delete: async (receiverId) => del(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),
|
|
106
|
+
/** Rotate receiver token. */
|
|
107
|
+
rotate: async (receiverId, graceSeconds) => post(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}/rotate`, {
|
|
108
|
+
grace_seconds: graceSeconds ?? 300
|
|
109
|
+
})
|
|
110
|
+
};
|
|
111
|
+
}
|
|
112
|
+
};
|
|
113
|
+
function createConnectClient(ctx) {
|
|
114
|
+
return new ConnectClient(ctx);
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
export { ConnectClient, createConnectClient };
|
|
118
|
+
//# sourceMappingURL=index.js.map
|
|
119
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["import {\n type RequestContext,\n type Result,\n get,\n post,\n patch,\n del,\n} from '@reactor-cloud/shared';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/** Connector descriptor from the catalog. */\nexport interface ConnectorDescriptor {\n type_id: string;\n display_name: string;\n version: string;\n runtime: 'native' | 'manifest' | 'airbyte_container';\n auth: AuthDescriptor;\n streams: StreamDescriptor[];\n actions: ActionDescriptor[];\n webhooks: WebhookDescriptor[];\n capabilities: ConnectorCapabilities;\n rate_limits?: RateLimitDescriptor;\n doc_url?: string;\n}\n\n/** Authentication descriptor. */\nexport interface AuthDescriptor {\n kind: AuthKind;\n fields: AuthField[];\n test?: TestCallDescriptor;\n}\n\n/** Authentication kind. */\nexport type AuthKind =\n | { kind: 'oauth2'; authorize_url: string; token_url: string; scopes: string[]; pkce?: boolean; reactor_proxy?: boolean }\n | { kind: 'personal_access_token'; header: string; format: string }\n | { kind: 'basic' }\n | { kind: 'custom'; docs_url: string };\n\n/** Authentication field. */\nexport interface AuthField {\n name: string;\n label: string;\n sensitive?: boolean;\n required?: boolean;\n description?: string;\n}\n\n/** Test call descriptor. */\nexport interface TestCallDescriptor {\n method: string;\n path: string;\n success_codes?: number[];\n}\n\n/** Stream descriptor. */\nexport interface StreamDescriptor {\n name: string;\n json_schema: Record<string, unknown>;\n supported_modes: SyncMode[];\n cursor_field?: string[];\n primary_key?: string[][];\n supports_outbound?: boolean;\n source_defined?: boolean;\n}\n\n/** Sync mode for streams. */\nexport type SyncMode = 'full_refresh' | 'incremental_append' | 'incremental_dedup';\n\n/** Action descriptor. */\nexport interface ActionDescriptor {\n name: string;\n input_schema: Record<string, unknown>;\n output_schema: Record<string, unknown>;\n side_effects: SideEffectKind;\n dry_run: DryRunSupport;\n idempotency?: IdempotencyHint;\n}\n\n/** Side effect classification. */\nexport type SideEffectKind = 'reads' | 'mutates' | 'sends';\n\n/** Dry-run support level. */\nexport type DryRunSupport = 'native' | 'synthesized' | 'unsupported';\n\n/** Idempotency hint. */\nexport interface IdempotencyHint {\n key_path: string;\n ttl_seconds: number;\n}\n\n/** Webhook descriptor. */\nexport interface WebhookDescriptor {\n name: string;\n verification: VerificationKind;\n event_types: string[];\n replay_window_seconds?: number;\n setup_instructions?: string;\n}\n\n/** Webhook verification kind. */\nexport type VerificationKind =\n | { kind: 'hmac_sha256'; header: string; secret_field: string }\n | { kind: 'ed25519'; header: string; key_id_header?: string }\n | { kind: 'custom'; docs_url: string };\n\n/** Connector capabilities. */\nexport interface ConnectorCapabilities {\n sandbox_mode?: boolean;\n vendor_test_mode?: boolean;\n cdc?: boolean;\n incremental?: boolean;\n schema_discovery?: boolean;\n}\n\n/** Rate limit descriptor. */\nexport interface RateLimitDescriptor {\n requests_per_second?: number;\n requests_per_minute?: number;\n requests_per_hour?: number;\n requests_per_day?: number;\n concurrent_requests?: number;\n}\n\n/** Connector instance. */\nexport interface Instance {\n id: string;\n connector_type: string;\n name: string;\n config: Record<string, unknown>;\n status: InstanceStatus;\n created_at: string;\n updated_at: string;\n}\n\n/** Instance status. */\nexport type InstanceStatus = 'active' | 'inactive' | 'error' | 'pending_credentials';\n\n/** Connection status. */\nexport interface ConnectionStatus {\n status: 'succeeded' | 'failed';\n message?: string;\n}\n\n/** Action result. */\nexport interface ActionResult {\n output: unknown;\n dry_run?: boolean;\n}\n\n/** Webhook receiver. */\nexport interface Receiver {\n id: string;\n name: string;\n target: ReceiverTarget;\n status: 'active' | 'inactive';\n filter_expression?: string;\n created_at: string;\n updated_at: string;\n}\n\n/** Receiver target. */\nexport type ReceiverTarget =\n | { type: 'job'; name: string }\n | { type: 'stream'; connection: string }\n | { type: 'action'; instance: string; action: string }\n | { type: 'function'; name: string };\n\n/** Receiver with token (returned on create). */\nexport interface ReceiverWithToken extends Receiver {\n token: string;\n}\n\n/** Rotate token response. */\nexport interface RotateTokenResponse {\n new_token: string;\n old_token_expires_at: string;\n}\n\n// ============================================================================\n// Options\n// ============================================================================\n\n/** Options for creating an instance. */\nexport interface CreateInstanceOptions {\n name: string;\n config?: Record<string, unknown>;\n}\n\n/** Options for updating an instance. */\nexport interface UpdateInstanceOptions {\n name?: string;\n config?: Record<string, unknown>;\n}\n\n/** Options for invoking an action. */\nexport interface InvokeActionOptions {\n input?: Record<string, unknown>;\n dryRun?: boolean;\n idempotencyKey?: string;\n}\n\n/** Options for creating a receiver. */\nexport interface CreateReceiverOptions {\n name: string;\n target: ReceiverTarget;\n filterExpression?: string;\n}\n\n/** Options for listing instances. */\nexport interface ListInstancesOptions {\n connectorType?: string;\n status?: InstanceStatus;\n limit?: number;\n offset?: number;\n}\n\n// ============================================================================\n// Client\n// ============================================================================\n\n/** Connect client for managing connectors and integrations. */\nexport class ConnectClient {\n constructor(private ctx: RequestContext) {}\n\n // ----------------------------------------\n // Catalog\n // ----------------------------------------\n\n /** Access the connector catalog. */\n get catalog() {\n return {\n /** List available connectors. */\n list: async (): Promise<Result<ConnectorDescriptor[]>> =>\n get(this.ctx, '/connect/v1/catalog'),\n\n /** Get connector details. */\n get: async (connectorType: string): Promise<Result<ConnectorDescriptor>> =>\n get(this.ctx, `/connect/v1/catalog/${encodeURIComponent(connectorType)}`),\n };\n }\n\n // ----------------------------------------\n // Instances\n // ----------------------------------------\n\n /** Manage connector instances. */\n get instances() {\n return {\n /** List instances. */\n list: async (options?: ListInstancesOptions): Promise<Result<Instance[]>> => {\n const params = new URLSearchParams();\n if (options?.connectorType) params.set('connector_type', options.connectorType);\n if (options?.status) params.set('status', options.status);\n if (options?.limit) params.set('limit', String(options.limit));\n if (options?.offset) params.set('offset', String(options.offset));\n const query = params.toString();\n return get(this.ctx, `/connect/v1/instances${query ? '?' + query : ''}`);\n },\n\n /** Create a new instance. */\n create: async (\n connectorType: string,\n options: CreateInstanceOptions\n ): Promise<Result<Instance>> =>\n post(this.ctx, '/connect/v1/instances', {\n connector_type: connectorType,\n name: options.name,\n config: options.config ?? {},\n }),\n\n /** Get instance details. */\n get: async (instanceId: string): Promise<Result<Instance>> =>\n get(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),\n\n /** Update an instance. */\n update: async (\n instanceId: string,\n options: UpdateInstanceOptions\n ): Promise<Result<Instance>> =>\n patch(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`, options),\n\n /** Delete an instance. */\n delete: async (instanceId: string): Promise<Result<void>> =>\n del(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}`),\n\n /** Test instance credentials. */\n check: async (instanceId: string): Promise<Result<ConnectionStatus>> =>\n post(this.ctx, `/connect/v1/instances/${encodeURIComponent(instanceId)}/check`, {}),\n\n /** Set credentials for an instance. */\n setCredentials: async (\n instanceId: string,\n credentials: Record<string, unknown>\n ): Promise<Result<void>> =>\n post(\n this.ctx,\n `/connect/v1/instances/${encodeURIComponent(instanceId)}/credentials`,\n credentials\n ),\n };\n }\n\n // ----------------------------------------\n // Actions\n // ----------------------------------------\n\n /**\n * Invoke an action on a connector instance.\n *\n * @example\n * ```ts\n * const result = await connect.invoke('stripe-prod', 'createCustomer', {\n * input: { email: 'user@example.com', name: 'Test User' },\n * dryRun: true,\n * });\n * ```\n */\n async invoke(\n instanceId: string,\n action: string,\n options?: InvokeActionOptions\n ): Promise<Result<ActionResult>> {\n const headers: Record<string, string> = {};\n if (options?.idempotencyKey) {\n headers['Idempotency-Key'] = options.idempotencyKey;\n }\n\n return post(\n this.ctx,\n `/connect/v1/instances/${encodeURIComponent(instanceId)}/actions/${encodeURIComponent(action)}`,\n {\n input: options?.input ?? {},\n dry_run: options?.dryRun ?? false,\n },\n { headers }\n );\n }\n\n // ----------------------------------------\n // Receivers\n // ----------------------------------------\n\n /** Manage webhook receivers. */\n get receivers() {\n return {\n /** List receivers. */\n list: async (): Promise<Result<Receiver[]>> =>\n get(this.ctx, '/connect/v1/receivers'),\n\n /** Create a new receiver. */\n create: async (options: CreateReceiverOptions): Promise<Result<ReceiverWithToken>> =>\n post(this.ctx, '/connect/v1/receivers', {\n name: options.name,\n target: options.target,\n filter_expression: options.filterExpression,\n }),\n\n /** Get receiver details. */\n get: async (receiverId: string): Promise<Result<Receiver>> =>\n get(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),\n\n /** Delete a receiver. */\n delete: async (receiverId: string): Promise<Result<void>> =>\n del(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}`),\n\n /** Rotate receiver token. */\n rotate: async (\n receiverId: string,\n graceSeconds?: number\n ): Promise<Result<RotateTokenResponse>> =>\n post(this.ctx, `/connect/v1/receivers/${encodeURIComponent(receiverId)}/rotate`, {\n grace_seconds: graceSeconds ?? 300,\n }),\n };\n }\n}\n\n/**\n * Create a Connect client.\n *\n * @example\n * ```ts\n * import { createClient } from '@reactor-cloud/client';\n * import { createConnectClient } from '@reactor-cloud/connect';\n *\n * const reactor = createClient({ endpoint: 'https://api.example.com' });\n * const connect = createConnectClient(reactor.context);\n *\n * // List available connectors\n * const { data: connectors } = await connect.catalog.list();\n *\n * // Create a Stripe instance\n * const { data: instance } = await connect.instances.create('stripe', {\n * name: 'stripe-prod',\n * config: { api_key: 'sk_test_...' },\n * });\n *\n * // Invoke an action\n * const { data: result } = await connect.invoke(instance.id, 'createCustomer', {\n * input: { email: 'user@example.com' },\n * dryRun: true,\n * });\n * ```\n */\nexport function createConnectClient(ctx: RequestContext): ConnectClient {\n return new ConnectClient(ctx);\n}\n"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@reactor-cloud/connect",
|
|
3
|
+
"version": "0.2.0",
|
|
4
|
+
"description": "Connect client for Reactor JS SDK - connectors and integrations",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"reactor",
|
|
7
|
+
"sdk",
|
|
8
|
+
"connect",
|
|
9
|
+
"connectors",
|
|
10
|
+
"integrations",
|
|
11
|
+
"api"
|
|
12
|
+
],
|
|
13
|
+
"license": "MIT",
|
|
14
|
+
"author": "Reactor Team",
|
|
15
|
+
"type": "module",
|
|
16
|
+
"sideEffects": false,
|
|
17
|
+
"exports": {
|
|
18
|
+
".": {
|
|
19
|
+
"import": {
|
|
20
|
+
"types": "./dist/index.d.ts",
|
|
21
|
+
"default": "./dist/index.js"
|
|
22
|
+
},
|
|
23
|
+
"require": {
|
|
24
|
+
"types": "./dist/index.d.cts",
|
|
25
|
+
"default": "./dist/index.cjs"
|
|
26
|
+
}
|
|
27
|
+
},
|
|
28
|
+
"./package.json": "./package.json"
|
|
29
|
+
},
|
|
30
|
+
"main": "./dist/index.cjs",
|
|
31
|
+
"module": "./dist/index.js",
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"files": [
|
|
34
|
+
"dist"
|
|
35
|
+
],
|
|
36
|
+
"dependencies": {
|
|
37
|
+
"@reactor-cloud/shared": "0.2.0"
|
|
38
|
+
},
|
|
39
|
+
"devDependencies": {
|
|
40
|
+
"typescript": "^5.7.2",
|
|
41
|
+
"vitest": "^2.1.8"
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"build": "tsup",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"typecheck": "tsc --noEmit",
|
|
47
|
+
"clean": "rm -rf dist .turbo"
|
|
48
|
+
}
|
|
49
|
+
}
|