@checkstack/integration-common 0.0.2
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/CHANGELOG.md +46 -0
- package/package.json +27 -0
- package/src/index.ts +64 -0
- package/src/permissions.ts +12 -0
- package/src/plugin-metadata.ts +9 -0
- package/src/routes.ts +15 -0
- package/src/rpc-contract.ts +311 -0
- package/src/schemas.ts +306 -0
- package/src/signals.ts +31 -0
- package/tsconfig.json +6 -0
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
# @checkstack/integration-common
|
|
2
|
+
|
|
3
|
+
## 0.0.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d20d274: Initial release of all @checkstack packages. Rebranded from Checkmate to Checkstack with new npm organization @checkstack and domain checkstack.dev.
|
|
8
|
+
- Updated dependencies [d20d274]
|
|
9
|
+
- @checkstack/common@0.0.2
|
|
10
|
+
- @checkstack/signal-common@0.0.2
|
|
11
|
+
|
|
12
|
+
## 0.1.1
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [a65e002]
|
|
17
|
+
- @checkstack/common@0.2.0
|
|
18
|
+
- @checkstack/signal-common@0.1.1
|
|
19
|
+
|
|
20
|
+
## 0.1.0
|
|
21
|
+
|
|
22
|
+
### Minor Changes
|
|
23
|
+
|
|
24
|
+
- 4dd644d: Enable external application (API key) access to management endpoints
|
|
25
|
+
|
|
26
|
+
Changed `userType: "user"` to `userType: "authenticated"` for 52 endpoints across 5 packages, allowing external applications (service accounts with API keys) to call these endpoints programmatically while maintaining RBAC permission checks:
|
|
27
|
+
|
|
28
|
+
- **incident-common**: createIncident, updateIncident, addUpdate, resolveIncident, deleteIncident
|
|
29
|
+
- **maintenance-common**: createMaintenance, updateMaintenance, addUpdate, closeMaintenance, deleteMaintenance
|
|
30
|
+
- **catalog-common**: System CRUD, Group CRUD, addSystemToGroup, removeSystemFromGroup
|
|
31
|
+
- **healthcheck-common**: Configuration management, system associations, retention config, detailed history
|
|
32
|
+
- **integration-common**: Subscription management, connection management, event discovery, delivery logs
|
|
33
|
+
|
|
34
|
+
This enables automation use cases such as:
|
|
35
|
+
|
|
36
|
+
- Creating incidents from external monitoring systems (Prometheus, Grafana)
|
|
37
|
+
- Scheduling maintenances from CI/CD pipelines
|
|
38
|
+
- Managing catalog systems from infrastructure-as-code tools
|
|
39
|
+
- Configuring health checks from deployment scripts
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- Updated dependencies [ffc28f6]
|
|
44
|
+
- Updated dependencies [b55fae6]
|
|
45
|
+
- @checkstack/common@0.1.0
|
|
46
|
+
- @checkstack/signal-common@0.1.0
|
package/package.json
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@checkstack/integration-common",
|
|
3
|
+
"version": "0.0.2",
|
|
4
|
+
"type": "module",
|
|
5
|
+
"exports": {
|
|
6
|
+
".": {
|
|
7
|
+
"types": "./src/index.ts",
|
|
8
|
+
"import": "./src/index.ts"
|
|
9
|
+
}
|
|
10
|
+
},
|
|
11
|
+
"dependencies": {
|
|
12
|
+
"@checkstack/common": "workspace:*",
|
|
13
|
+
"@checkstack/signal-common": "workspace:*",
|
|
14
|
+
"@orpc/contract": "^1.13.2",
|
|
15
|
+
"zod": "^4.0.0"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@checkstack/tsconfig": "workspace:*",
|
|
19
|
+
"typescript": "^5.7.2",
|
|
20
|
+
"@checkstack/scripts": "workspace:*"
|
|
21
|
+
},
|
|
22
|
+
"scripts": {
|
|
23
|
+
"typecheck": "tsc --noEmit",
|
|
24
|
+
"lint": "bun run lint:code",
|
|
25
|
+
"lint:code": "eslint . --max-warnings 0"
|
|
26
|
+
}
|
|
27
|
+
}
|
package/src/index.ts
ADDED
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
// Schemas - Zod validators for API contracts
|
|
2
|
+
export {
|
|
3
|
+
// Delivery status
|
|
4
|
+
DeliveryStatusSchema,
|
|
5
|
+
type DeliveryStatus,
|
|
6
|
+
// Webhook subscriptions
|
|
7
|
+
WebhookSubscriptionSchema,
|
|
8
|
+
type WebhookSubscription,
|
|
9
|
+
CreateSubscriptionInputSchema,
|
|
10
|
+
type CreateSubscriptionInput,
|
|
11
|
+
UpdateSubscriptionInputSchema,
|
|
12
|
+
type UpdateSubscriptionInput,
|
|
13
|
+
// Delivery logs
|
|
14
|
+
DeliveryLogSchema,
|
|
15
|
+
type DeliveryLog,
|
|
16
|
+
DeliveryLogQueryInputSchema,
|
|
17
|
+
type DeliveryLogQueryInput,
|
|
18
|
+
// Provider info
|
|
19
|
+
IntegrationProviderInfoSchema,
|
|
20
|
+
type IntegrationProviderInfo,
|
|
21
|
+
// Event info
|
|
22
|
+
IntegrationEventInfoSchema,
|
|
23
|
+
type IntegrationEventInfo,
|
|
24
|
+
// Result schemas (for API validation)
|
|
25
|
+
IntegrationDeliveryResultSchema,
|
|
26
|
+
TestConnectionResultSchema,
|
|
27
|
+
// Connection management
|
|
28
|
+
ProviderConnectionSchema,
|
|
29
|
+
type ProviderConnection,
|
|
30
|
+
ProviderConnectionRedactedSchema,
|
|
31
|
+
type ProviderConnectionRedacted,
|
|
32
|
+
CreateConnectionInputSchema,
|
|
33
|
+
type CreateConnectionInput,
|
|
34
|
+
UpdateConnectionInputSchema,
|
|
35
|
+
type UpdateConnectionInput,
|
|
36
|
+
GetConnectionOptionsInputSchema,
|
|
37
|
+
type GetConnectionOptionsInput,
|
|
38
|
+
ConnectionOptionSchema,
|
|
39
|
+
type ConnectionOptionOutput,
|
|
40
|
+
// Payload property hints
|
|
41
|
+
PayloadPropertySchema,
|
|
42
|
+
type PayloadProperty,
|
|
43
|
+
EventPayloadSchemaOutputSchema,
|
|
44
|
+
type EventPayloadSchemaOutput,
|
|
45
|
+
} from "./schemas";
|
|
46
|
+
|
|
47
|
+
// NOTE: All backend-only types (IntegrationProvider, IntegrationDeliveryContext, etc.)
|
|
48
|
+
// are defined in @checkstack/integration-backend/provider-types.
|
|
49
|
+
// Frontend code should only use the Zod schemas above for API contracts.
|
|
50
|
+
|
|
51
|
+
// Permissions
|
|
52
|
+
export * from "./permissions";
|
|
53
|
+
|
|
54
|
+
// RPC Contract
|
|
55
|
+
export * from "./rpc-contract";
|
|
56
|
+
|
|
57
|
+
// Signals
|
|
58
|
+
export * from "./signals";
|
|
59
|
+
|
|
60
|
+
// Plugin Metadata
|
|
61
|
+
export * from "./plugin-metadata";
|
|
62
|
+
|
|
63
|
+
// Routes
|
|
64
|
+
export { integrationRoutes } from "./routes";
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import { createPermission } from "@checkstack/common";
|
|
2
|
+
|
|
3
|
+
export const permissions = {
|
|
4
|
+
/** Manage webhook integrations and view delivery logs */
|
|
5
|
+
integrationManage: createPermission(
|
|
6
|
+
"integration",
|
|
7
|
+
"manage",
|
|
8
|
+
"Manage webhook integrations and view delivery logs"
|
|
9
|
+
),
|
|
10
|
+
};
|
|
11
|
+
|
|
12
|
+
export const permissionList = Object.values(permissions);
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { definePluginMetadata } from "@checkstack/common";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Plugin metadata for the integration plugin.
|
|
5
|
+
* Exported from the common package so both backend and frontend can reference it.
|
|
6
|
+
*/
|
|
7
|
+
export const pluginMetadata = definePluginMetadata({
|
|
8
|
+
pluginId: "integration",
|
|
9
|
+
});
|
package/src/routes.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { createRoutes } from "@checkstack/common";
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Route definitions for the integration plugin.
|
|
5
|
+
*/
|
|
6
|
+
export const integrationRoutes = createRoutes("integration", {
|
|
7
|
+
/** Main integrations management page */
|
|
8
|
+
list: "/",
|
|
9
|
+
/** Delivery logs page (all logs) */
|
|
10
|
+
logs: "/logs",
|
|
11
|
+
/** Delivery logs filtered by subscription */
|
|
12
|
+
deliveryLogs: "/logs/:subscriptionId",
|
|
13
|
+
/** Provider connections management */
|
|
14
|
+
connections: "/connections/:providerId",
|
|
15
|
+
});
|
|
@@ -0,0 +1,311 @@
|
|
|
1
|
+
import { oc } from "@orpc/contract";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { permissions } from "./permissions";
|
|
4
|
+
import { pluginMetadata } from "./plugin-metadata";
|
|
5
|
+
import {
|
|
6
|
+
createClientDefinition,
|
|
7
|
+
type ProcedureMetadata,
|
|
8
|
+
} from "@checkstack/common";
|
|
9
|
+
import {
|
|
10
|
+
WebhookSubscriptionSchema,
|
|
11
|
+
CreateSubscriptionInputSchema,
|
|
12
|
+
UpdateSubscriptionInputSchema,
|
|
13
|
+
DeliveryLogSchema,
|
|
14
|
+
DeliveryLogQueryInputSchema,
|
|
15
|
+
IntegrationProviderInfoSchema,
|
|
16
|
+
IntegrationEventInfoSchema,
|
|
17
|
+
TestConnectionResultSchema,
|
|
18
|
+
ProviderConnectionRedactedSchema,
|
|
19
|
+
CreateConnectionInputSchema,
|
|
20
|
+
UpdateConnectionInputSchema,
|
|
21
|
+
GetConnectionOptionsInputSchema,
|
|
22
|
+
ConnectionOptionSchema,
|
|
23
|
+
EventPayloadSchemaOutputSchema,
|
|
24
|
+
} from "./schemas";
|
|
25
|
+
|
|
26
|
+
// Base builder with full metadata support (userType + permissions)
|
|
27
|
+
const _base = oc.$meta<ProcedureMetadata>({});
|
|
28
|
+
|
|
29
|
+
// Integration RPC Contract
|
|
30
|
+
export const integrationContract = {
|
|
31
|
+
// ==========================================================================
|
|
32
|
+
// SUBSCRIPTION MANAGEMENT (Admin only)
|
|
33
|
+
// ==========================================================================
|
|
34
|
+
|
|
35
|
+
/** List all webhook subscriptions */
|
|
36
|
+
listSubscriptions: _base
|
|
37
|
+
.meta({
|
|
38
|
+
userType: "authenticated",
|
|
39
|
+
permissions: [permissions.integrationManage.id],
|
|
40
|
+
})
|
|
41
|
+
.input(
|
|
42
|
+
z.object({
|
|
43
|
+
page: z.number().min(1).default(1),
|
|
44
|
+
pageSize: z.number().min(1).max(100).default(20),
|
|
45
|
+
providerId: z.string().optional(),
|
|
46
|
+
eventType: z.string().optional(),
|
|
47
|
+
enabled: z.boolean().optional(),
|
|
48
|
+
})
|
|
49
|
+
)
|
|
50
|
+
.output(
|
|
51
|
+
z.object({
|
|
52
|
+
subscriptions: z.array(WebhookSubscriptionSchema),
|
|
53
|
+
total: z.number(),
|
|
54
|
+
})
|
|
55
|
+
),
|
|
56
|
+
|
|
57
|
+
/** Get a single subscription by ID */
|
|
58
|
+
getSubscription: _base
|
|
59
|
+
.meta({
|
|
60
|
+
userType: "authenticated",
|
|
61
|
+
permissions: [permissions.integrationManage.id],
|
|
62
|
+
})
|
|
63
|
+
.input(z.object({ id: z.string() }))
|
|
64
|
+
.output(WebhookSubscriptionSchema),
|
|
65
|
+
|
|
66
|
+
/** Create a new webhook subscription */
|
|
67
|
+
createSubscription: _base
|
|
68
|
+
.meta({
|
|
69
|
+
userType: "authenticated",
|
|
70
|
+
permissions: [permissions.integrationManage.id],
|
|
71
|
+
})
|
|
72
|
+
.input(CreateSubscriptionInputSchema)
|
|
73
|
+
.output(WebhookSubscriptionSchema),
|
|
74
|
+
|
|
75
|
+
/** Update an existing subscription */
|
|
76
|
+
updateSubscription: _base
|
|
77
|
+
.meta({
|
|
78
|
+
userType: "authenticated",
|
|
79
|
+
permissions: [permissions.integrationManage.id],
|
|
80
|
+
})
|
|
81
|
+
.input(UpdateSubscriptionInputSchema)
|
|
82
|
+
.output(WebhookSubscriptionSchema),
|
|
83
|
+
|
|
84
|
+
/** Delete a subscription */
|
|
85
|
+
deleteSubscription: _base
|
|
86
|
+
.meta({
|
|
87
|
+
userType: "authenticated",
|
|
88
|
+
permissions: [permissions.integrationManage.id],
|
|
89
|
+
})
|
|
90
|
+
.input(z.object({ id: z.string() }))
|
|
91
|
+
.output(z.object({ success: z.boolean() })),
|
|
92
|
+
|
|
93
|
+
/** Toggle subscription enabled state */
|
|
94
|
+
toggleSubscription: _base
|
|
95
|
+
.meta({
|
|
96
|
+
userType: "authenticated",
|
|
97
|
+
permissions: [permissions.integrationManage.id],
|
|
98
|
+
})
|
|
99
|
+
.input(z.object({ id: z.string(), enabled: z.boolean() }))
|
|
100
|
+
.output(z.object({ success: z.boolean() })),
|
|
101
|
+
|
|
102
|
+
// ==========================================================================
|
|
103
|
+
// PROVIDER DISCOVERY (Admin only)
|
|
104
|
+
// ==========================================================================
|
|
105
|
+
|
|
106
|
+
/** List all registered integration providers */
|
|
107
|
+
listProviders: _base
|
|
108
|
+
.meta({
|
|
109
|
+
userType: "authenticated",
|
|
110
|
+
permissions: [permissions.integrationManage.id],
|
|
111
|
+
})
|
|
112
|
+
.output(z.array(IntegrationProviderInfoSchema)),
|
|
113
|
+
|
|
114
|
+
/** Test a provider connection with given config */
|
|
115
|
+
testProviderConnection: _base
|
|
116
|
+
.meta({
|
|
117
|
+
userType: "authenticated",
|
|
118
|
+
permissions: [permissions.integrationManage.id],
|
|
119
|
+
})
|
|
120
|
+
.input(
|
|
121
|
+
z.object({
|
|
122
|
+
providerId: z.string(),
|
|
123
|
+
config: z.record(z.string(), z.unknown()),
|
|
124
|
+
})
|
|
125
|
+
)
|
|
126
|
+
.output(TestConnectionResultSchema),
|
|
127
|
+
|
|
128
|
+
// ==========================================================================
|
|
129
|
+
// CONNECTION MANAGEMENT (Admin only)
|
|
130
|
+
// Generic CRUD for site-wide provider connections
|
|
131
|
+
// ==========================================================================
|
|
132
|
+
|
|
133
|
+
/** List all connections for a provider */
|
|
134
|
+
listConnections: _base
|
|
135
|
+
.meta({
|
|
136
|
+
userType: "authenticated",
|
|
137
|
+
permissions: [permissions.integrationManage.id],
|
|
138
|
+
})
|
|
139
|
+
.input(z.object({ providerId: z.string() }))
|
|
140
|
+
.output(z.array(ProviderConnectionRedactedSchema)),
|
|
141
|
+
|
|
142
|
+
/** Get a single connection (redacted) */
|
|
143
|
+
getConnection: _base
|
|
144
|
+
.meta({
|
|
145
|
+
userType: "authenticated",
|
|
146
|
+
permissions: [permissions.integrationManage.id],
|
|
147
|
+
})
|
|
148
|
+
.input(z.object({ connectionId: z.string() }))
|
|
149
|
+
.output(ProviderConnectionRedactedSchema),
|
|
150
|
+
|
|
151
|
+
/** Create a new provider connection */
|
|
152
|
+
createConnection: _base
|
|
153
|
+
.meta({
|
|
154
|
+
userType: "authenticated",
|
|
155
|
+
permissions: [permissions.integrationManage.id],
|
|
156
|
+
})
|
|
157
|
+
.input(CreateConnectionInputSchema)
|
|
158
|
+
.output(ProviderConnectionRedactedSchema),
|
|
159
|
+
|
|
160
|
+
/** Update a provider connection */
|
|
161
|
+
updateConnection: _base
|
|
162
|
+
.meta({
|
|
163
|
+
userType: "authenticated",
|
|
164
|
+
permissions: [permissions.integrationManage.id],
|
|
165
|
+
})
|
|
166
|
+
.input(UpdateConnectionInputSchema)
|
|
167
|
+
.output(ProviderConnectionRedactedSchema),
|
|
168
|
+
|
|
169
|
+
/** Delete a provider connection */
|
|
170
|
+
deleteConnection: _base
|
|
171
|
+
.meta({
|
|
172
|
+
userType: "authenticated",
|
|
173
|
+
permissions: [permissions.integrationManage.id],
|
|
174
|
+
})
|
|
175
|
+
.input(z.object({ connectionId: z.string() }))
|
|
176
|
+
.output(z.object({ success: z.boolean() })),
|
|
177
|
+
|
|
178
|
+
/** Test a saved connection */
|
|
179
|
+
testConnection: _base
|
|
180
|
+
.meta({
|
|
181
|
+
userType: "authenticated",
|
|
182
|
+
permissions: [permissions.integrationManage.id],
|
|
183
|
+
})
|
|
184
|
+
.input(z.object({ connectionId: z.string() }))
|
|
185
|
+
.output(TestConnectionResultSchema),
|
|
186
|
+
|
|
187
|
+
/** Get dynamic options for cascading dropdowns */
|
|
188
|
+
getConnectionOptions: _base
|
|
189
|
+
.meta({
|
|
190
|
+
userType: "authenticated",
|
|
191
|
+
permissions: [permissions.integrationManage.id],
|
|
192
|
+
})
|
|
193
|
+
.input(GetConnectionOptionsInputSchema)
|
|
194
|
+
.output(z.array(ConnectionOptionSchema)),
|
|
195
|
+
|
|
196
|
+
// ==========================================================================
|
|
197
|
+
// EVENT DISCOVERY (Admin only)
|
|
198
|
+
// ==========================================================================
|
|
199
|
+
|
|
200
|
+
/** List all registered integration events */
|
|
201
|
+
listEventTypes: _base
|
|
202
|
+
.meta({
|
|
203
|
+
userType: "authenticated",
|
|
204
|
+
permissions: [permissions.integrationManage.id],
|
|
205
|
+
})
|
|
206
|
+
.output(z.array(IntegrationEventInfoSchema)),
|
|
207
|
+
|
|
208
|
+
/** Get events grouped by category */
|
|
209
|
+
getEventsByCategory: _base
|
|
210
|
+
.meta({
|
|
211
|
+
userType: "authenticated",
|
|
212
|
+
permissions: [permissions.integrationManage.id],
|
|
213
|
+
})
|
|
214
|
+
.output(
|
|
215
|
+
z.array(
|
|
216
|
+
z.object({
|
|
217
|
+
category: z.string(),
|
|
218
|
+
events: z.array(IntegrationEventInfoSchema),
|
|
219
|
+
})
|
|
220
|
+
)
|
|
221
|
+
),
|
|
222
|
+
|
|
223
|
+
/** Get payload schema for a specific event with flattened property list for template hints */
|
|
224
|
+
getEventPayloadSchema: _base
|
|
225
|
+
.meta({
|
|
226
|
+
userType: "authenticated",
|
|
227
|
+
permissions: [permissions.integrationManage.id],
|
|
228
|
+
})
|
|
229
|
+
.input(z.object({ eventId: z.string() }))
|
|
230
|
+
.output(EventPayloadSchemaOutputSchema),
|
|
231
|
+
|
|
232
|
+
// ==========================================================================
|
|
233
|
+
// DELIVERY LOGS (Admin only)
|
|
234
|
+
// ==========================================================================
|
|
235
|
+
|
|
236
|
+
/** Get delivery logs with filtering */
|
|
237
|
+
getDeliveryLogs: _base
|
|
238
|
+
.meta({
|
|
239
|
+
userType: "authenticated",
|
|
240
|
+
permissions: [permissions.integrationManage.id],
|
|
241
|
+
})
|
|
242
|
+
.input(DeliveryLogQueryInputSchema)
|
|
243
|
+
.output(
|
|
244
|
+
z.object({
|
|
245
|
+
logs: z.array(DeliveryLogSchema),
|
|
246
|
+
total: z.number(),
|
|
247
|
+
})
|
|
248
|
+
),
|
|
249
|
+
|
|
250
|
+
/** Get a single delivery log entry */
|
|
251
|
+
getDeliveryLog: _base
|
|
252
|
+
.meta({
|
|
253
|
+
userType: "authenticated",
|
|
254
|
+
permissions: [permissions.integrationManage.id],
|
|
255
|
+
})
|
|
256
|
+
.input(z.object({ id: z.string() }))
|
|
257
|
+
.output(DeliveryLogSchema),
|
|
258
|
+
|
|
259
|
+
/** Retry a failed delivery */
|
|
260
|
+
retryDelivery: _base
|
|
261
|
+
.meta({
|
|
262
|
+
userType: "authenticated",
|
|
263
|
+
permissions: [permissions.integrationManage.id],
|
|
264
|
+
})
|
|
265
|
+
.input(z.object({ logId: z.string() }))
|
|
266
|
+
.output(z.object({ success: z.boolean(), message: z.string().optional() })),
|
|
267
|
+
|
|
268
|
+
/** Get delivery statistics for dashboard */
|
|
269
|
+
getDeliveryStats: _base
|
|
270
|
+
.meta({
|
|
271
|
+
userType: "authenticated",
|
|
272
|
+
permissions: [permissions.integrationManage.id],
|
|
273
|
+
})
|
|
274
|
+
.input(
|
|
275
|
+
z.object({
|
|
276
|
+
/** Time range in hours (default: 24) */
|
|
277
|
+
hours: z.number().min(1).max(720).default(24),
|
|
278
|
+
})
|
|
279
|
+
)
|
|
280
|
+
.output(
|
|
281
|
+
z.object({
|
|
282
|
+
total: z.number(),
|
|
283
|
+
successful: z.number(),
|
|
284
|
+
failed: z.number(),
|
|
285
|
+
retrying: z.number(),
|
|
286
|
+
pending: z.number(),
|
|
287
|
+
byEvent: z.array(
|
|
288
|
+
z.object({
|
|
289
|
+
eventType: z.string(),
|
|
290
|
+
count: z.number(),
|
|
291
|
+
})
|
|
292
|
+
),
|
|
293
|
+
byProvider: z.array(
|
|
294
|
+
z.object({
|
|
295
|
+
providerId: z.string(),
|
|
296
|
+
count: z.number(),
|
|
297
|
+
})
|
|
298
|
+
),
|
|
299
|
+
})
|
|
300
|
+
),
|
|
301
|
+
};
|
|
302
|
+
|
|
303
|
+
// Export contract type
|
|
304
|
+
export type IntegrationContract = typeof integrationContract;
|
|
305
|
+
|
|
306
|
+
// Export client definition for type-safe forPlugin usage
|
|
307
|
+
// Use: const client = rpcApi.forPlugin(IntegrationApi);
|
|
308
|
+
export const IntegrationApi = createClientDefinition(
|
|
309
|
+
integrationContract,
|
|
310
|
+
pluginMetadata
|
|
311
|
+
);
|
package/src/schemas.ts
ADDED
|
@@ -0,0 +1,306 @@
|
|
|
1
|
+
import { z } from "zod";
|
|
2
|
+
|
|
3
|
+
// =============================================================================
|
|
4
|
+
// Webhook Subscription Schemas
|
|
5
|
+
// =============================================================================
|
|
6
|
+
|
|
7
|
+
/** Status of a webhook delivery attempt */
|
|
8
|
+
export const DeliveryStatusSchema = z.enum([
|
|
9
|
+
"pending",
|
|
10
|
+
"success",
|
|
11
|
+
"failed",
|
|
12
|
+
"retrying",
|
|
13
|
+
]);
|
|
14
|
+
export type DeliveryStatus = z.infer<typeof DeliveryStatusSchema>;
|
|
15
|
+
|
|
16
|
+
/** Webhook subscription configuration */
|
|
17
|
+
export const WebhookSubscriptionSchema = z.object({
|
|
18
|
+
id: z.string(),
|
|
19
|
+
name: z.string().min(1).max(100),
|
|
20
|
+
description: z.string().optional(),
|
|
21
|
+
|
|
22
|
+
/** Fully qualified provider ID: {pluginId}.{providerId} */
|
|
23
|
+
providerId: z.string(),
|
|
24
|
+
|
|
25
|
+
/** Provider-specific configuration (validated against provider schema) */
|
|
26
|
+
providerConfig: z.record(z.string(), z.unknown()),
|
|
27
|
+
|
|
28
|
+
/** Single event to subscribe to (fully qualified event ID) */
|
|
29
|
+
eventId: z.string(),
|
|
30
|
+
|
|
31
|
+
/** Optional: Filter by system IDs */
|
|
32
|
+
systemFilter: z.array(z.string()).optional(),
|
|
33
|
+
|
|
34
|
+
/** Subscription state */
|
|
35
|
+
enabled: z.boolean().default(true),
|
|
36
|
+
|
|
37
|
+
createdAt: z.coerce.date(),
|
|
38
|
+
updatedAt: z.coerce.date(),
|
|
39
|
+
});
|
|
40
|
+
export type WebhookSubscription = z.infer<typeof WebhookSubscriptionSchema>;
|
|
41
|
+
|
|
42
|
+
/** Input for creating a webhook subscription */
|
|
43
|
+
export const CreateSubscriptionInputSchema = z.object({
|
|
44
|
+
name: z.string().min(1).max(100),
|
|
45
|
+
description: z.string().optional(),
|
|
46
|
+
providerId: z.string(),
|
|
47
|
+
providerConfig: z.record(z.string(), z.unknown()),
|
|
48
|
+
/** Single event to subscribe to */
|
|
49
|
+
eventId: z.string(),
|
|
50
|
+
systemFilter: z.array(z.string()).optional(),
|
|
51
|
+
});
|
|
52
|
+
export type CreateSubscriptionInput = z.infer<
|
|
53
|
+
typeof CreateSubscriptionInputSchema
|
|
54
|
+
>;
|
|
55
|
+
|
|
56
|
+
/** Input for updating a webhook subscription */
|
|
57
|
+
export const UpdateSubscriptionInputSchema = z.object({
|
|
58
|
+
id: z.string(),
|
|
59
|
+
updates: z.object({
|
|
60
|
+
name: z.string().min(1).max(100).optional(),
|
|
61
|
+
description: z.string().optional(),
|
|
62
|
+
providerConfig: z.record(z.string(), z.unknown()).optional(),
|
|
63
|
+
eventId: z.string().optional(),
|
|
64
|
+
systemFilter: z.array(z.string()).optional(),
|
|
65
|
+
enabled: z.boolean().optional(),
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
export type UpdateSubscriptionInput = z.infer<
|
|
69
|
+
typeof UpdateSubscriptionInputSchema
|
|
70
|
+
>;
|
|
71
|
+
|
|
72
|
+
// =============================================================================
|
|
73
|
+
// Delivery Log Schemas
|
|
74
|
+
// =============================================================================
|
|
75
|
+
|
|
76
|
+
/** Delivery log entry */
|
|
77
|
+
export const DeliveryLogSchema = z.object({
|
|
78
|
+
id: z.string(),
|
|
79
|
+
subscriptionId: z.string(),
|
|
80
|
+
subscriptionName: z.string().optional(),
|
|
81
|
+
|
|
82
|
+
eventType: z.string(),
|
|
83
|
+
eventPayload: z.record(z.string(), z.unknown()),
|
|
84
|
+
|
|
85
|
+
status: DeliveryStatusSchema,
|
|
86
|
+
attempts: z.number(),
|
|
87
|
+
lastAttemptAt: z.coerce.date().optional(),
|
|
88
|
+
nextRetryAt: z.coerce.date().optional(),
|
|
89
|
+
|
|
90
|
+
externalId: z.string().optional(),
|
|
91
|
+
errorMessage: z.string().optional(),
|
|
92
|
+
|
|
93
|
+
createdAt: z.coerce.date(),
|
|
94
|
+
});
|
|
95
|
+
export type DeliveryLog = z.infer<typeof DeliveryLogSchema>;
|
|
96
|
+
|
|
97
|
+
/** Input for querying delivery logs */
|
|
98
|
+
export const DeliveryLogQueryInputSchema = z.object({
|
|
99
|
+
subscriptionId: z.string().optional(),
|
|
100
|
+
eventType: z.string().optional(),
|
|
101
|
+
status: DeliveryStatusSchema.optional(),
|
|
102
|
+
page: z.number().min(1).default(1),
|
|
103
|
+
pageSize: z.number().min(1).max(100).default(20),
|
|
104
|
+
});
|
|
105
|
+
export type DeliveryLogQueryInput = z.infer<typeof DeliveryLogQueryInputSchema>;
|
|
106
|
+
|
|
107
|
+
// =============================================================================
|
|
108
|
+
// Integration Provider Schemas
|
|
109
|
+
// =============================================================================
|
|
110
|
+
|
|
111
|
+
/** Documentation schema for provider setup help */
|
|
112
|
+
export const ProviderDocumentationSchema = z
|
|
113
|
+
.object({
|
|
114
|
+
/** Brief setup instructions (rendered as markdown) */
|
|
115
|
+
setupGuide: z.string().optional(),
|
|
116
|
+
/** Example request body (JSON string for syntax highlighting) */
|
|
117
|
+
examplePayload: z.string().optional(),
|
|
118
|
+
/** HTTP headers that will be sent with each request */
|
|
119
|
+
headers: z
|
|
120
|
+
.array(
|
|
121
|
+
z.object({
|
|
122
|
+
name: z.string(),
|
|
123
|
+
description: z.string(),
|
|
124
|
+
})
|
|
125
|
+
)
|
|
126
|
+
.optional(),
|
|
127
|
+
/** Link to external documentation */
|
|
128
|
+
externalDocsUrl: z.string().url().optional(),
|
|
129
|
+
})
|
|
130
|
+
.optional();
|
|
131
|
+
|
|
132
|
+
/** Provider info for API responses */
|
|
133
|
+
export const IntegrationProviderInfoSchema = z.object({
|
|
134
|
+
/** Qualified ID: {pluginId}.{providerId} */
|
|
135
|
+
qualifiedId: z.string(),
|
|
136
|
+
/** Display name */
|
|
137
|
+
displayName: z.string(),
|
|
138
|
+
/** Description */
|
|
139
|
+
description: z.string().optional(),
|
|
140
|
+
/** Lucide icon name */
|
|
141
|
+
icon: z.string().optional(),
|
|
142
|
+
/** Owner plugin ID */
|
|
143
|
+
ownerPluginId: z.string(),
|
|
144
|
+
/** Events this provider can handle (undefined = all) */
|
|
145
|
+
supportedEvents: z.array(z.string()).optional(),
|
|
146
|
+
/** JSON Schema for provider config (for DynamicForm) */
|
|
147
|
+
configSchema: z.record(z.string(), z.unknown()),
|
|
148
|
+
/** Whether this provider has a connectionSchema (requires connection management) */
|
|
149
|
+
hasConnectionSchema: z.boolean().default(false),
|
|
150
|
+
/** JSON Schema for connection config (for DynamicForm in connection management) */
|
|
151
|
+
connectionSchema: z.record(z.string(), z.unknown()).optional(),
|
|
152
|
+
/** Optional documentation to help users configure their endpoints */
|
|
153
|
+
documentation: ProviderDocumentationSchema,
|
|
154
|
+
});
|
|
155
|
+
export type IntegrationProviderInfo = z.infer<
|
|
156
|
+
typeof IntegrationProviderInfoSchema
|
|
157
|
+
>;
|
|
158
|
+
|
|
159
|
+
// =============================================================================
|
|
160
|
+
// Provider Connection Schemas
|
|
161
|
+
// =============================================================================
|
|
162
|
+
|
|
163
|
+
/** Provider connection record (site-wide credentials) */
|
|
164
|
+
export const ProviderConnectionSchema = z.object({
|
|
165
|
+
/** Unique connection ID */
|
|
166
|
+
id: z.string(),
|
|
167
|
+
/** Qualified provider ID this connection belongs to */
|
|
168
|
+
providerId: z.string(),
|
|
169
|
+
/** Display name for this connection */
|
|
170
|
+
name: z.string().min(1).max(100),
|
|
171
|
+
/** Connection configuration (provider-specific, secrets redacted for API) */
|
|
172
|
+
config: z.record(z.string(), z.unknown()),
|
|
173
|
+
createdAt: z.coerce.date(),
|
|
174
|
+
updatedAt: z.coerce.date(),
|
|
175
|
+
});
|
|
176
|
+
export type ProviderConnection = z.infer<typeof ProviderConnectionSchema>;
|
|
177
|
+
|
|
178
|
+
/** Redacted connection for API responses (no secrets) */
|
|
179
|
+
export const ProviderConnectionRedactedSchema = z.object({
|
|
180
|
+
id: z.string(),
|
|
181
|
+
providerId: z.string(),
|
|
182
|
+
name: z.string(),
|
|
183
|
+
/** Redacted config (secret fields removed) */
|
|
184
|
+
configPreview: z.record(z.string(), z.unknown()),
|
|
185
|
+
createdAt: z.coerce.date(),
|
|
186
|
+
updatedAt: z.coerce.date(),
|
|
187
|
+
});
|
|
188
|
+
export type ProviderConnectionRedacted = z.infer<
|
|
189
|
+
typeof ProviderConnectionRedactedSchema
|
|
190
|
+
>;
|
|
191
|
+
|
|
192
|
+
/** Input for creating a provider connection */
|
|
193
|
+
export const CreateConnectionInputSchema = z.object({
|
|
194
|
+
/** Qualified provider ID */
|
|
195
|
+
providerId: z.string(),
|
|
196
|
+
/** Display name */
|
|
197
|
+
name: z.string().min(1).max(100),
|
|
198
|
+
/** Provider-specific connection config (validated against connectionSchema) */
|
|
199
|
+
config: z.record(z.string(), z.unknown()),
|
|
200
|
+
});
|
|
201
|
+
export type CreateConnectionInput = z.infer<typeof CreateConnectionInputSchema>;
|
|
202
|
+
|
|
203
|
+
/** Input for updating a provider connection */
|
|
204
|
+
export const UpdateConnectionInputSchema = z.object({
|
|
205
|
+
connectionId: z.string(),
|
|
206
|
+
updates: z.object({
|
|
207
|
+
name: z.string().min(1).max(100).optional(),
|
|
208
|
+
/** Partial config update (only provided fields are updated) */
|
|
209
|
+
config: z.record(z.string(), z.unknown()).optional(),
|
|
210
|
+
}),
|
|
211
|
+
});
|
|
212
|
+
export type UpdateConnectionInput = z.infer<typeof UpdateConnectionInputSchema>;
|
|
213
|
+
|
|
214
|
+
/** Input for getting connection options (cascading dropdowns) */
|
|
215
|
+
export const GetConnectionOptionsInputSchema = z.object({
|
|
216
|
+
providerId: z.string(),
|
|
217
|
+
connectionId: z.string(),
|
|
218
|
+
resolverName: z.string(),
|
|
219
|
+
context: z.record(z.string(), z.unknown()).default({}),
|
|
220
|
+
});
|
|
221
|
+
export type GetConnectionOptionsInput = z.infer<
|
|
222
|
+
typeof GetConnectionOptionsInputSchema
|
|
223
|
+
>;
|
|
224
|
+
|
|
225
|
+
/** Option returned from getConnectionOptions */
|
|
226
|
+
export const ConnectionOptionSchema = z.object({
|
|
227
|
+
value: z.string(),
|
|
228
|
+
label: z.string(),
|
|
229
|
+
description: z.string().optional(),
|
|
230
|
+
});
|
|
231
|
+
export type ConnectionOptionOutput = z.infer<typeof ConnectionOptionSchema>;
|
|
232
|
+
|
|
233
|
+
// =============================================================================
|
|
234
|
+
// Integration Event Schemas
|
|
235
|
+
// =============================================================================
|
|
236
|
+
|
|
237
|
+
/** Integration event info for API responses */
|
|
238
|
+
export const IntegrationEventInfoSchema = z.object({
|
|
239
|
+
/** Fully qualified event ID: {pluginId}.{hookId} */
|
|
240
|
+
eventId: z.string(),
|
|
241
|
+
/** Display name for UI */
|
|
242
|
+
displayName: z.string(),
|
|
243
|
+
/** Description of when this event fires */
|
|
244
|
+
description: z.string().optional(),
|
|
245
|
+
/** Category for UI grouping */
|
|
246
|
+
category: z.string().optional(),
|
|
247
|
+
/** Owner plugin ID */
|
|
248
|
+
ownerPluginId: z.string(),
|
|
249
|
+
/** JSON Schema for payload preview */
|
|
250
|
+
payloadSchema: z.record(z.string(), z.unknown()),
|
|
251
|
+
});
|
|
252
|
+
export type IntegrationEventInfo = z.infer<typeof IntegrationEventInfoSchema>;
|
|
253
|
+
|
|
254
|
+
// =============================================================================
|
|
255
|
+
// Delivery Result Schema
|
|
256
|
+
// =============================================================================
|
|
257
|
+
|
|
258
|
+
/** Result of a provider delivery attempt */
|
|
259
|
+
export const IntegrationDeliveryResultSchema = z.object({
|
|
260
|
+
success: z.boolean(),
|
|
261
|
+
externalId: z.string().optional(),
|
|
262
|
+
error: z.string().optional(),
|
|
263
|
+
retryAfterMs: z.number().optional(),
|
|
264
|
+
});
|
|
265
|
+
export type IntegrationDeliveryResult = z.infer<
|
|
266
|
+
typeof IntegrationDeliveryResultSchema
|
|
267
|
+
>;
|
|
268
|
+
|
|
269
|
+
// =============================================================================
|
|
270
|
+
// Test Connection Schema
|
|
271
|
+
// =============================================================================
|
|
272
|
+
|
|
273
|
+
/** Result of testing a provider connection */
|
|
274
|
+
export const TestConnectionResultSchema = z.object({
|
|
275
|
+
success: z.boolean(),
|
|
276
|
+
message: z.string().optional(),
|
|
277
|
+
});
|
|
278
|
+
export type TestConnectionResult = z.infer<typeof TestConnectionResultSchema>;
|
|
279
|
+
|
|
280
|
+
// =============================================================================
|
|
281
|
+
// Payload Property Schema (for template hints)
|
|
282
|
+
// =============================================================================
|
|
283
|
+
|
|
284
|
+
/** A single payload property available for templating */
|
|
285
|
+
export const PayloadPropertySchema = z.object({
|
|
286
|
+
/** Full path to the property, e.g., "payload.incident.title" */
|
|
287
|
+
path: z.string(),
|
|
288
|
+
/** Type of the property, e.g., "string", "number", "boolean" */
|
|
289
|
+
type: z.string(),
|
|
290
|
+
/** Optional description of the property */
|
|
291
|
+
description: z.string().optional(),
|
|
292
|
+
});
|
|
293
|
+
export type PayloadProperty = z.infer<typeof PayloadPropertySchema>;
|
|
294
|
+
|
|
295
|
+
/** Output schema for getEventPayloadSchema */
|
|
296
|
+
export const EventPayloadSchemaOutputSchema = z.object({
|
|
297
|
+
/** Event ID */
|
|
298
|
+
eventId: z.string(),
|
|
299
|
+
/** Full JSON Schema for the payload */
|
|
300
|
+
payloadSchema: z.record(z.string(), z.unknown()),
|
|
301
|
+
/** Flattened list of available properties for template hints */
|
|
302
|
+
availableProperties: z.array(PayloadPropertySchema),
|
|
303
|
+
});
|
|
304
|
+
export type EventPayloadSchemaOutput = z.infer<
|
|
305
|
+
typeof EventPayloadSchemaOutputSchema
|
|
306
|
+
>;
|
package/src/signals.ts
ADDED
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { createSignal } from "@checkstack/signal-common";
|
|
2
|
+
import { z } from "zod";
|
|
3
|
+
import { DeliveryStatusSchema } from "./schemas";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* Signal emitted when a delivery completes (success or failure).
|
|
7
|
+
* Used to update the delivery logs UI in real-time.
|
|
8
|
+
*/
|
|
9
|
+
export const INTEGRATION_DELIVERY_COMPLETED = createSignal(
|
|
10
|
+
"INTEGRATION_DELIVERY_COMPLETED",
|
|
11
|
+
z.object({
|
|
12
|
+
logId: z.string(),
|
|
13
|
+
subscriptionId: z.string(),
|
|
14
|
+
eventType: z.string(),
|
|
15
|
+
status: DeliveryStatusSchema,
|
|
16
|
+
externalId: z.string().optional(),
|
|
17
|
+
errorMessage: z.string().optional(),
|
|
18
|
+
})
|
|
19
|
+
);
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Signal emitted when a subscription is created, updated, or deleted.
|
|
23
|
+
* Used to refresh the subscriptions list in real-time.
|
|
24
|
+
*/
|
|
25
|
+
export const INTEGRATION_SUBSCRIPTION_CHANGED = createSignal(
|
|
26
|
+
"INTEGRATION_SUBSCRIPTION_CHANGED",
|
|
27
|
+
z.object({
|
|
28
|
+
action: z.enum(["created", "updated", "deleted"]),
|
|
29
|
+
subscriptionId: z.string(),
|
|
30
|
+
})
|
|
31
|
+
);
|