@checkstack/integration-frontend 0.2.18 → 0.2.20
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
CHANGED
|
@@ -1,5 +1,48 @@
|
|
|
1
1
|
# @checkstack/integration-frontend
|
|
2
2
|
|
|
3
|
+
## 0.2.20
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- d1a2796: Enforce stricter code quality standards and eliminate AI slop anti-patterns.
|
|
8
|
+
|
|
9
|
+
**New utility**
|
|
10
|
+
|
|
11
|
+
- `extractErrorMessage(error, fallback?)` in `@checkstack/common` for consistent error extraction
|
|
12
|
+
|
|
13
|
+
**ESLint rules**
|
|
14
|
+
|
|
15
|
+
- `react-hooks/rules-of-hooks` and `exhaustive-deps` for hook correctness
|
|
16
|
+
- `no-console` in frontend packages — forces `toast` over silent `console.error`
|
|
17
|
+
- `no-restricted-syntax` banning `instanceof Error` — forces `extractErrorMessage`
|
|
18
|
+
- Custom `no-eslint-disable-any` rule preventing `@typescript-eslint/no-explicit-any` circumvention
|
|
19
|
+
|
|
20
|
+
**Refactoring**
|
|
21
|
+
|
|
22
|
+
- Replace 141 `instanceof Error` boilerplate patterns across the codebase
|
|
23
|
+
- Replace swallowed `console.error` with user-visible `toast.error()` feedback
|
|
24
|
+
- Remove 15 redundant `as` type casts in IntegrationsPage and ProviderConnectionsPage
|
|
25
|
+
- Consolidate 3 identical callback handlers into `handleDialogClose`
|
|
26
|
+
- Fix conditional React hook call in `FormField.tsx`
|
|
27
|
+
- Fix unstable useMemo deps in `Dashboard.tsx`
|
|
28
|
+
- Replace `useEffect`→`setState` with derived `useMemo` in `RegisterPage.tsx`
|
|
29
|
+
- Rewrite `keystore.test.ts` with typed `DrizzleMockChain` (eliminating 7 `any` suppressions)
|
|
30
|
+
- Delete obvious comments in `encryption.ts` and Teams `provider.ts`
|
|
31
|
+
|
|
32
|
+
- Updated dependencies [d1a2796]
|
|
33
|
+
- @checkstack/common@0.6.5
|
|
34
|
+
- @checkstack/ui@1.2.1
|
|
35
|
+
- @checkstack/frontend-api@0.3.9
|
|
36
|
+
- @checkstack/integration-common@0.2.8
|
|
37
|
+
- @checkstack/signal-frontend@0.0.15
|
|
38
|
+
|
|
39
|
+
## 0.2.19
|
|
40
|
+
|
|
41
|
+
### Patch Changes
|
|
42
|
+
|
|
43
|
+
- Updated dependencies [23c80bc]
|
|
44
|
+
- @checkstack/ui@1.2.0
|
|
45
|
+
|
|
3
46
|
## 0.2.18
|
|
4
47
|
|
|
5
48
|
### Patch Changes
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@checkstack/integration-frontend",
|
|
3
|
-
"version": "0.2.
|
|
3
|
+
"version": "0.2.20",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "src/index.tsx",
|
|
6
6
|
"checkstack": {
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@checkstack/frontend-api": "0.3.8",
|
|
17
17
|
"@checkstack/signal-frontend": "0.0.14",
|
|
18
18
|
"@checkstack/common": "0.6.4",
|
|
19
|
-
"@checkstack/ui": "1.
|
|
19
|
+
"@checkstack/ui": "1.2.0",
|
|
20
20
|
"react": "^18.2.0",
|
|
21
21
|
"react-router-dom": "^6.22.0",
|
|
22
22
|
"lucide-react": "^0.344.0"
|
|
@@ -24,7 +24,7 @@
|
|
|
24
24
|
"devDependencies": {
|
|
25
25
|
"typescript": "^5.0.0",
|
|
26
26
|
"@types/react": "^18.2.0",
|
|
27
|
-
"@checkstack/tsconfig": "0.0.
|
|
27
|
+
"@checkstack/tsconfig": "0.0.5",
|
|
28
28
|
"@checkstack/scripts": "0.1.2"
|
|
29
29
|
}
|
|
30
30
|
}
|
|
@@ -24,7 +24,7 @@ import {
|
|
|
24
24
|
type LucideIconName,
|
|
25
25
|
} from "@checkstack/ui";
|
|
26
26
|
import { usePluginClient } from "@checkstack/frontend-api";
|
|
27
|
-
import { resolveRoute } from "@checkstack/common";
|
|
27
|
+
import { resolveRoute, extractErrorMessage } from "@checkstack/common";
|
|
28
28
|
import {
|
|
29
29
|
IntegrationApi,
|
|
30
30
|
integrationRoutes,
|
|
@@ -111,11 +111,7 @@ export const SubscriptionDialog = ({
|
|
|
111
111
|
setSaving(false);
|
|
112
112
|
},
|
|
113
113
|
onError: (error) => {
|
|
114
|
-
toast.error(
|
|
115
|
-
error instanceof Error
|
|
116
|
-
? error.message
|
|
117
|
-
: "Failed to create subscription",
|
|
118
|
-
);
|
|
114
|
+
toast.error(extractErrorMessage(error, "Failed to create subscription"));
|
|
119
115
|
setSaving(false);
|
|
120
116
|
},
|
|
121
117
|
});
|
|
@@ -128,11 +124,7 @@ export const SubscriptionDialog = ({
|
|
|
128
124
|
setSaving(false);
|
|
129
125
|
},
|
|
130
126
|
onError: (error) => {
|
|
131
|
-
toast.error(
|
|
132
|
-
error instanceof Error
|
|
133
|
-
? error.message
|
|
134
|
-
: "Failed to update subscription",
|
|
135
|
-
);
|
|
127
|
+
toast.error(extractErrorMessage(error, "Failed to update subscription"));
|
|
136
128
|
setSaving(false);
|
|
137
129
|
},
|
|
138
130
|
});
|
|
@@ -144,11 +136,7 @@ export const SubscriptionDialog = ({
|
|
|
144
136
|
onOpenChange(false);
|
|
145
137
|
},
|
|
146
138
|
onError: (error) => {
|
|
147
|
-
toast.error(
|
|
148
|
-
error instanceof Error
|
|
149
|
-
? error.message
|
|
150
|
-
: "Failed to delete subscription",
|
|
151
|
-
);
|
|
139
|
+
toast.error(extractErrorMessage(error, "Failed to delete subscription"));
|
|
152
140
|
},
|
|
153
141
|
});
|
|
154
142
|
|
|
@@ -303,11 +291,7 @@ export const SubscriptionDialog = ({
|
|
|
303
291
|
value: opt.value,
|
|
304
292
|
label: opt.label,
|
|
305
293
|
}));
|
|
306
|
-
} catch
|
|
307
|
-
console.error(
|
|
308
|
-
`Failed to fetch options for ${resolverName}:`,
|
|
309
|
-
error,
|
|
310
|
-
);
|
|
294
|
+
} catch {
|
|
311
295
|
return [];
|
|
312
296
|
}
|
|
313
297
|
};
|
|
@@ -320,7 +304,7 @@ export const SubscriptionDialog = ({
|
|
|
320
304
|
formValues: Record<string, unknown>,
|
|
321
305
|
) => Promise<{ value: string; label: string }[]>
|
|
322
306
|
>;
|
|
323
|
-
//
|
|
307
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps -- getOptionsMutation is a TanStack mutation object that changes identity every render; including it would destroy the Proxy on each render, breaking in-flight requests
|
|
324
308
|
}, [selectedProvider, selectedConnectionId]);
|
|
325
309
|
|
|
326
310
|
return (
|
|
@@ -90,8 +90,7 @@ export const DeliveryLogsPage = () => {
|
|
|
90
90
|
toast.error(result.message ?? "Failed to retry delivery");
|
|
91
91
|
}
|
|
92
92
|
},
|
|
93
|
-
onError: (
|
|
94
|
-
console.error("Failed to retry delivery:", error);
|
|
93
|
+
onError: () => {
|
|
95
94
|
toast.error("Failed to retry delivery");
|
|
96
95
|
},
|
|
97
96
|
onSettled: () => {
|
|
@@ -26,7 +26,7 @@ import {
|
|
|
26
26
|
type LucideIconName,
|
|
27
27
|
} from "@checkstack/ui";
|
|
28
28
|
import { usePluginClient } from "@checkstack/frontend-api";
|
|
29
|
-
import { resolveRoute } from "@checkstack/common";
|
|
29
|
+
import { resolveRoute, extractErrorMessage} from "@checkstack/common";
|
|
30
30
|
import {
|
|
31
31
|
IntegrationApi,
|
|
32
32
|
integrationRoutes,
|
|
@@ -67,9 +67,7 @@ export const IntegrationsPage = () => {
|
|
|
67
67
|
},
|
|
68
68
|
onError: (error) => {
|
|
69
69
|
toast.error(
|
|
70
|
-
error
|
|
71
|
-
? error.message
|
|
72
|
-
: "Failed to toggle subscription",
|
|
70
|
+
extractErrorMessage(error, "Failed to toggle subscription"),
|
|
73
71
|
);
|
|
74
72
|
},
|
|
75
73
|
});
|
|
@@ -91,28 +89,14 @@ export const IntegrationsPage = () => {
|
|
|
91
89
|
const getProviderInfo = (
|
|
92
90
|
providerId: string,
|
|
93
91
|
): IntegrationProviderInfo | undefined => {
|
|
94
|
-
return (
|
|
95
|
-
(p) => p.qualifiedId === providerId,
|
|
96
|
-
);
|
|
92
|
+
return providers.find((p) => p.qualifiedId === providerId);
|
|
97
93
|
};
|
|
98
94
|
|
|
99
95
|
const handleToggle = (id: string, enabled: boolean) => {
|
|
100
96
|
toggleMutation.mutate({ id, enabled });
|
|
101
97
|
};
|
|
102
98
|
|
|
103
|
-
const
|
|
104
|
-
void refetchSubs();
|
|
105
|
-
setDialogOpen(false);
|
|
106
|
-
setSelectedSubscription(undefined);
|
|
107
|
-
};
|
|
108
|
-
|
|
109
|
-
const handleUpdated = () => {
|
|
110
|
-
void refetchSubs();
|
|
111
|
-
setDialogOpen(false);
|
|
112
|
-
setSelectedSubscription(undefined);
|
|
113
|
-
};
|
|
114
|
-
|
|
115
|
-
const handleDeleted = () => {
|
|
99
|
+
const handleDialogClose = () => {
|
|
116
100
|
void refetchSubs();
|
|
117
101
|
setDialogOpen(false);
|
|
118
102
|
setSelectedSubscription(undefined);
|
|
@@ -239,8 +223,8 @@ export const IntegrationsPage = () => {
|
|
|
239
223
|
<div className="p-2 rounded-lg bg-muted">
|
|
240
224
|
<DynamicIcon
|
|
241
225
|
name={
|
|
242
|
-
(provider?.icon ??
|
|
243
|
-
"Webhook"
|
|
226
|
+
(provider?.icon as LucideIconName | undefined) ??
|
|
227
|
+
"Webhook"
|
|
244
228
|
}
|
|
245
229
|
className="h-5 w-5 text-muted-foreground"
|
|
246
230
|
/>
|
|
@@ -305,14 +289,14 @@ export const IntegrationsPage = () => {
|
|
|
305
289
|
description="Providers handle the delivery of events to external systems"
|
|
306
290
|
/>
|
|
307
291
|
<div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-4">
|
|
308
|
-
{
|
|
292
|
+
{providers.map((provider) => (
|
|
309
293
|
<Card key={provider.qualifiedId}>
|
|
310
294
|
<CardContent className="p-4">
|
|
311
295
|
<div className="flex items-center justify-between">
|
|
312
296
|
<div className="flex items-center gap-3">
|
|
313
297
|
<div className="p-2 rounded-lg bg-muted">
|
|
314
298
|
<DynamicIcon
|
|
315
|
-
name={(provider.icon ?? "Webhook"
|
|
299
|
+
name={(provider.icon as LucideIconName | undefined) ?? "Webhook"}
|
|
316
300
|
className="h-6 w-6"
|
|
317
301
|
/>
|
|
318
302
|
</div>
|
|
@@ -341,7 +325,7 @@ export const IntegrationsPage = () => {
|
|
|
341
325
|
</CardContent>
|
|
342
326
|
</Card>
|
|
343
327
|
))}
|
|
344
|
-
{
|
|
328
|
+
{providers.length === 0 && (
|
|
345
329
|
<Card className="col-span-full">
|
|
346
330
|
<CardContent className="p-4">
|
|
347
331
|
<div className="text-center text-muted-foreground py-4">
|
|
@@ -361,11 +345,11 @@ export const IntegrationsPage = () => {
|
|
|
361
345
|
setDialogOpen(open);
|
|
362
346
|
if (!open) setSelectedSubscription(undefined);
|
|
363
347
|
}}
|
|
364
|
-
providers={providers
|
|
348
|
+
providers={providers}
|
|
365
349
|
subscription={selectedSubscription}
|
|
366
|
-
onCreated={
|
|
367
|
-
onUpdated={
|
|
368
|
-
onDeleted={
|
|
350
|
+
onCreated={handleDialogClose}
|
|
351
|
+
onUpdated={handleDialogClose}
|
|
352
|
+
onDeleted={handleDialogClose}
|
|
369
353
|
/>
|
|
370
354
|
</PageLayout>
|
|
371
355
|
);
|
|
@@ -45,11 +45,10 @@ import {
|
|
|
45
45
|
type LucideIconName,
|
|
46
46
|
} from "@checkstack/ui";
|
|
47
47
|
import { usePluginClient } from "@checkstack/frontend-api";
|
|
48
|
-
import { resolveRoute } from "@checkstack/common";
|
|
48
|
+
import { resolveRoute, extractErrorMessage } from "@checkstack/common";
|
|
49
49
|
import {
|
|
50
50
|
IntegrationApi,
|
|
51
51
|
integrationRoutes,
|
|
52
|
-
type IntegrationProviderInfo,
|
|
53
52
|
type ProviderConnectionRedacted,
|
|
54
53
|
} from "@checkstack/integration-common";
|
|
55
54
|
|
|
@@ -95,9 +94,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
95
94
|
);
|
|
96
95
|
|
|
97
96
|
const loading = providersLoading || connectionsLoading;
|
|
98
|
-
const provider = (
|
|
99
|
-
(p) => p.qualifiedId === providerId,
|
|
100
|
-
);
|
|
97
|
+
const provider = providers.find((p) => p.qualifiedId === providerId);
|
|
101
98
|
|
|
102
99
|
// Mutations
|
|
103
100
|
const createMutation = client.createConnection.useMutation({
|
|
@@ -110,9 +107,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
110
107
|
setSaving(false);
|
|
111
108
|
},
|
|
112
109
|
onError: (error) => {
|
|
113
|
-
toast.error(
|
|
114
|
-
error instanceof Error ? error.message : "Failed to create connection",
|
|
115
|
-
);
|
|
110
|
+
toast.error(extractErrorMessage(error, "Failed to create connection"));
|
|
116
111
|
setSaving(false);
|
|
117
112
|
},
|
|
118
113
|
});
|
|
@@ -126,9 +121,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
126
121
|
setSaving(false);
|
|
127
122
|
},
|
|
128
123
|
onError: (error) => {
|
|
129
|
-
toast.error(
|
|
130
|
-
error instanceof Error ? error.message : "Failed to update connection",
|
|
131
|
-
);
|
|
124
|
+
toast.error(extractErrorMessage(error, "Failed to update connection"));
|
|
132
125
|
setSaving(false);
|
|
133
126
|
},
|
|
134
127
|
});
|
|
@@ -141,9 +134,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
141
134
|
toast.success("Connection deleted");
|
|
142
135
|
},
|
|
143
136
|
onError: (error) => {
|
|
144
|
-
toast.error(
|
|
145
|
-
error instanceof Error ? error.message : "Failed to delete connection",
|
|
146
|
-
);
|
|
137
|
+
toast.error(extractErrorMessage(error, "Failed to delete connection"));
|
|
147
138
|
},
|
|
148
139
|
});
|
|
149
140
|
|
|
@@ -165,9 +156,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
165
156
|
...prev,
|
|
166
157
|
[variables.connectionId]: { success: false, message: "Test failed" },
|
|
167
158
|
}));
|
|
168
|
-
toast.error(
|
|
169
|
-
error instanceof Error ? error.message : "Connection test failed",
|
|
170
|
-
);
|
|
159
|
+
toast.error(extractErrorMessage(error, "Connection test failed"));
|
|
171
160
|
setTestingId(undefined);
|
|
172
161
|
},
|
|
173
162
|
});
|
|
@@ -275,11 +264,13 @@ export const ProviderConnectionsPage = () => {
|
|
|
275
264
|
</div>
|
|
276
265
|
}
|
|
277
266
|
>
|
|
278
|
-
{
|
|
267
|
+
{connections.length === 0 ? (
|
|
279
268
|
<EmptyState
|
|
280
269
|
icon={
|
|
281
270
|
<DynamicIcon
|
|
282
|
-
name={
|
|
271
|
+
name={
|
|
272
|
+
(provider?.icon as LucideIconName | undefined) ?? "Settings2"
|
|
273
|
+
}
|
|
283
274
|
className="h-12 w-12"
|
|
284
275
|
/>
|
|
285
276
|
}
|
|
@@ -296,7 +287,9 @@ export const ProviderConnectionsPage = () => {
|
|
|
296
287
|
<CardHeader>
|
|
297
288
|
<CardTitle className="flex items-center gap-2">
|
|
298
289
|
<DynamicIcon
|
|
299
|
-
name={
|
|
290
|
+
name={
|
|
291
|
+
(provider?.icon as LucideIconName | undefined) ?? "Settings2"
|
|
292
|
+
}
|
|
300
293
|
className="h-5 w-5"
|
|
301
294
|
/>
|
|
302
295
|
Connections
|
|
@@ -313,7 +306,7 @@ export const ProviderConnectionsPage = () => {
|
|
|
313
306
|
</TableRow>
|
|
314
307
|
</TableHeader>
|
|
315
308
|
<TableBody>
|
|
316
|
-
{
|
|
309
|
+
{connections.map((conn) => {
|
|
317
310
|
const testResult = testResults[conn.id];
|
|
318
311
|
const isTesting = testingId === conn.id;
|
|
319
312
|
|