@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 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"]}
@@ -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 };
@@ -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
+ }