@checkstack/integration-backend 0.1.30 → 0.3.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/src/index.ts CHANGED
@@ -13,39 +13,31 @@ import {
13
13
  } from "@checkstack/integration-common";
14
14
  import { resolveRoute } from "@checkstack/common";
15
15
  import type { PluginMetadata } from "@checkstack/common";
16
- import type {
17
- IntegrationEventDefinition,
18
- IntegrationProvider,
19
- } from "./provider-types";
16
+ import type { IntegrationProvider } from "./provider-types";
20
17
 
21
18
  import * as schema from "./schema";
22
- import {
23
- createIntegrationEventRegistry,
24
- type IntegrationEventRegistry,
25
- } from "./event-registry";
26
- import {
27
- createIntegrationProviderRegistry,
28
- type IntegrationProviderRegistry,
29
- } from "./provider-registry";
30
- import { createDeliveryCoordinator } from "./delivery-coordinator";
19
+ import { createIntegrationProviderRegistry } from "./provider-registry";
31
20
  import {
32
21
  createConnectionStore,
33
22
  type ConnectionStore,
34
23
  } from "./connection-store";
35
- import { subscribeToRegisteredEvents } from "./hook-subscriber";
36
24
  import { createIntegrationRouter } from "./router";
37
25
  import { registerSearchProvider } from "@checkstack/command-backend";
26
+ import {
27
+ secretResolverRef,
28
+ internalSecretsRef,
29
+ } from "@checkstack/secrets-backend";
38
30
 
39
31
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
40
32
  // Service References
41
33
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
42
34
 
43
35
  /**
44
- * Service reference for the connection store.
45
- * Provider plugins can inject this to access connection credentials.
36
+ * Service reference for the connection store. Provider plugins inject
37
+ * this to look up credentials when an automation action runs.
46
38
  */
47
39
  export const connectionStoreRef = createServiceRef<ConnectionStore>(
48
- "integration.connectionStore"
40
+ "integration.connectionStore",
49
41
  );
50
42
 
51
43
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
@@ -53,83 +45,45 @@ export const connectionStoreRef = createServiceRef<ConnectionStore>(
53
45
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
54
46
 
55
47
  /**
56
- * Extension point for registering integration events.
57
- * Plugins use this to expose their hooks for external webhook subscriptions.
58
- */
59
- export interface IntegrationEventExtensionPoint {
60
- /**
61
- * Register a hook as an integration event.
62
- * The event will be namespaced by the plugin's ID automatically.
63
- */
64
- registerEvent<T>(
65
- definition: IntegrationEventDefinition<T>,
66
- pluginMetadata: PluginMetadata
67
- ): void;
68
- }
69
-
70
- export const integrationEventExtensionPoint =
71
- createExtensionPoint<IntegrationEventExtensionPoint>(
72
- "integration.eventExtensionPoint"
73
- );
74
-
75
- /**
76
- * Extension point for registering integration providers.
77
- * Plugins use this to register webhook delivery providers.
48
+ * Extension point for registering integration providers. After the
49
+ * migration to the Automation Platform a provider is just the
50
+ * connection metadata + dropdown resolvers + a test endpoint — the
51
+ * per-event delivery work moved onto automation actions.
78
52
  */
79
53
  export interface IntegrationProviderExtensionPoint {
80
- /**
81
- * Register an integration provider.
82
- * The provider will be namespaced by the plugin's ID automatically.
83
- * @template TConfig - Per-subscription configuration type
84
- * @template TConnection - Site-wide connection configuration type (optional)
85
- */
86
- addProvider<TConfig, TConnection = undefined>(
87
- provider: IntegrationProvider<TConfig, TConnection>,
88
- pluginMetadata: PluginMetadata
54
+ addProvider<TConnection = undefined>(
55
+ provider: IntegrationProvider<TConnection>,
56
+ pluginMetadata: PluginMetadata,
89
57
  ): void;
90
58
  }
91
59
 
92
60
  export const integrationProviderExtensionPoint =
93
61
  createExtensionPoint<IntegrationProviderExtensionPoint>(
94
- "integration.providerExtensionPoint"
62
+ "integration.providerExtensionPoint",
95
63
  );
96
64
 
97
65
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
98
66
  // Plugin Definition
99
67
  // ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
100
68
 
69
+ interface EnvStash {
70
+ /** Set in `init`, used by `afterPluginsReady` for the credential migration. */
71
+ runCredentialMigration?: () => Promise<void>;
72
+ }
73
+
101
74
  export default createBackendPlugin({
102
75
  metadata: pluginMetadata,
103
76
 
104
77
  register(env) {
105
- // Create the registries
106
- const eventRegistry = createIntegrationEventRegistry();
107
78
  const providerRegistry = createIntegrationProviderRegistry();
108
79
 
109
- // Register static access rules
110
80
  env.registerAccessRules(integrationAccessRules);
111
81
 
112
- // Register the event extension point
113
- env.registerExtensionPoint(integrationEventExtensionPoint, {
114
- registerEvent: <T>(
115
- definition: IntegrationEventDefinition<T>,
116
- metadata: PluginMetadata
117
- ) => {
118
- // Type erasure: cast to unknown for storage (the registry handles this internally)
119
- eventRegistry.register(
120
- definition as IntegrationEventDefinition<unknown>,
121
- metadata
122
- );
123
- },
124
- });
125
-
126
- // Register the provider extension point
127
82
  env.registerExtensionPoint(integrationProviderExtensionPoint, {
128
83
  addProvider: (provider, metadata) => {
129
- // Type erasure: cast to unknown for storage (the registry handles this internally)
130
84
  providerRegistry.register(
131
85
  provider as IntegrationProvider<unknown>,
132
- metadata
86
+ metadata,
133
87
  );
134
88
  },
135
89
  });
@@ -140,167 +94,87 @@ export default createBackendPlugin({
140
94
  logger: coreServices.logger,
141
95
  rpc: coreServices.rpc,
142
96
  config: coreServices.config,
143
- signalService: coreServices.signalService,
144
- queueManager: coreServices.queueManager,
97
+ secretResolver: secretResolverRef,
98
+ internalSecrets: internalSecretsRef,
145
99
  },
146
100
  init: async ({
147
101
  logger,
148
- database,
149
102
  rpc,
150
103
  config,
151
- signalService,
152
- queueManager,
104
+ database,
105
+ secretResolver,
106
+ internalSecrets,
153
107
  }) => {
154
108
  logger.debug("🔌 Initializing Integration Backend...");
155
109
 
156
- const db = database;
157
-
158
- // Create connection store for generic connection management
159
110
  const connectionStore = createConnectionStore({
160
111
  configService: config,
161
112
  providerRegistry,
162
113
  logger,
114
+ // Unified credential resolution through the ONE secrets channel.
115
+ credentials: { secretResolver, internalSecrets },
163
116
  });
164
-
165
- // Publish connection store for provider plugins to inject
166
117
  env.registerService(connectionStoreRef, connectionStore);
118
+ // Stash the migration for afterPluginsReady (all providers + their
119
+ // connectionSchemas are registered only by then).
120
+ (env as unknown as EnvStash).runCredentialMigration = () =>
121
+ connectionStore.runCredentialMigration();
167
122
 
168
- // Create delivery coordinator
169
- const deliveryCoordinator = createDeliveryCoordinator({
170
- db,
171
- providerRegistry,
172
- connectionStore,
173
- queueManager,
174
- signalService,
175
- logger,
176
- });
177
-
178
- // Store for afterPluginsReady access
179
- (
180
- env as unknown as {
181
- eventRegistry: IntegrationEventRegistry;
182
- providerRegistry: IntegrationProviderRegistry;
183
- deliveryCoordinator: typeof deliveryCoordinator;
184
- }
185
- ).eventRegistry = eventRegistry;
186
- (
187
- env as unknown as {
188
- eventRegistry: IntegrationEventRegistry;
189
- providerRegistry: IntegrationProviderRegistry;
190
- deliveryCoordinator: typeof deliveryCoordinator;
191
- }
192
- ).providerRegistry = providerRegistry;
193
- (
194
- env as unknown as {
195
- eventRegistry: IntegrationEventRegistry;
196
- providerRegistry: IntegrationProviderRegistry;
197
- deliveryCoordinator: typeof deliveryCoordinator;
198
- }
199
- ).deliveryCoordinator = deliveryCoordinator;
200
-
201
- // Create and register the router
202
123
  const router = createIntegrationRouter({
203
- db,
204
- eventRegistry,
124
+ db: database,
205
125
  providerRegistry,
206
- deliveryCoordinator,
207
126
  connectionStore,
208
- signalService,
209
127
  logger,
210
128
  });
211
129
  rpc.registerRouter(router, integrationContract);
212
130
 
213
- // Register command palette commands
214
131
  registerSearchProvider({
215
132
  pluginMetadata,
216
133
  commands: [
217
134
  {
218
- id: "create",
219
- title: "Create Integration Subscription",
220
- subtitle: "Create a new subscription for integration events",
221
- iconName: "Webhook",
222
- route:
223
- resolveRoute(integrationRoutes.routes.list) + "?action=create",
224
- requiredAccessRules: [integrationAccess.manage],
225
- },
226
- {
227
- id: "manage",
228
- title: "Manage Integrations",
229
- subtitle: "Manage integration subscriptions and connections",
135
+ id: "connections",
136
+ title: "Manage Integration Connections",
137
+ subtitle: "Configure credentials for Jira, Teams, Webex, etc.",
230
138
  iconName: "Webhook",
231
139
  shortcuts: ["meta+shift+g", "ctrl+shift+g"],
232
140
  route: resolveRoute(integrationRoutes.routes.list),
233
141
  requiredAccessRules: [integrationAccess.manage],
234
142
  },
235
- {
236
- id: "logs",
237
- title: "View Integration Logs",
238
- subtitle: "View integration delivery logs",
239
- iconName: "FileText",
240
- route: resolveRoute(integrationRoutes.routes.logs),
241
- requiredAccessRules: [integrationAccess.manage],
242
- },
243
143
  ],
244
144
  });
245
145
 
246
- logger.debug("✅ Integration Backend initialized.");
247
- },
248
- afterPluginsReady: async ({ logger, onHook }) => {
249
- // Get registries from env
250
- const stored = env as unknown as {
251
- eventRegistry: IntegrationEventRegistry;
252
- providerRegistry: IntegrationProviderRegistry;
253
- deliveryCoordinator: ReturnType<typeof createDeliveryCoordinator>;
254
- };
255
-
256
- const events = stored.eventRegistry.getEvents();
257
- const providers = stored.providerRegistry.getProviders();
258
-
259
- logger.debug(
260
- `🔌 Registered ${events.length} integration events: ${events
261
- .map((e) => e.eventId)
262
- .join(", ")}`
263
- );
264
-
265
146
  logger.debug(
266
- `📡 Registered ${providers.length} integration providers: ${providers
267
- .map((p) => p.qualifiedId)
268
- .join(", ")}`
147
+ `📡 Integration Backend init complete with ${providerRegistry.getProviders().length} providers`,
269
148
  );
149
+ },
270
150
 
271
- // Subscribe to all registered integration events
272
- // Uses work-queue mode to ensure only ONE instance processes each event
273
- subscribeToRegisteredEvents({
274
- onHook,
275
- eventRegistry: stored.eventRegistry,
276
- deliveryCoordinator: stored.deliveryCoordinator,
277
- logger,
278
- });
279
-
280
- // Start the delivery worker
281
- await stored.deliveryCoordinator.startWorker();
282
-
283
- logger.debug("✅ Integration Backend afterPluginsReady complete.");
151
+ // Consolidate legacy inline connection credentials onto the secrets
152
+ // platform once every provider (and its connectionSchema) is
153
+ // registered. Idempotent + parity-verified + reversible (backup).
154
+ afterPluginsReady: async ({ logger }) => {
155
+ try {
156
+ await (env as unknown as EnvStash).runCredentialMigration?.();
157
+ } catch (error) {
158
+ logger.error(
159
+ `Connection credential migration failed: ${String(error)}`,
160
+ );
161
+ }
284
162
  },
285
163
  });
286
164
  },
287
165
  });
288
166
 
289
- // Re-export extension points for consumer plugins
290
- export { integrationEventExtensionPoint as eventExtensionPoint };
167
+ // ─── Re-exports ─────────────────────────────────────────────────────────
168
+
291
169
  export { integrationProviderExtensionPoint as providerExtensionPoint };
292
170
 
293
- // Re-export provider types for consumer plugins
294
- // All backend-only types are defined here (not in integration-common)
295
171
  export type {
296
- IntegrationEventDefinition,
297
- IntegrationDeliveryContext,
298
- IntegrationDeliveryResult,
299
172
  TestConnectionResult,
300
173
  ProviderDocumentation,
301
174
  ConnectionOption,
302
175
  GetConnectionOptionsParams,
303
176
  IntegrationProvider,
304
177
  RegisteredIntegrationProvider,
305
- RegisteredIntegrationEvent,
306
178
  } from "./provider-types";
179
+
180
+ export type { ConnectionStore } from "./connection-store";