@zyphr-dev/webhook-portal 0.1.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/dist/index.cjs ADDED
@@ -0,0 +1,301 @@
1
+ 'use strict';
2
+
3
+ var jsxRuntime = require('react/jsx-runtime');
4
+ var react = require('react');
5
+
6
+ const DEFAULT_BASE_URL = 'https://api.zyphr.dev/v1/waas-portal';
7
+ function usePortalApi({ token, baseUrl }) {
8
+ const base = baseUrl || DEFAULT_BASE_URL;
9
+ const tokenRef = react.useRef(token);
10
+ tokenRef.current = token;
11
+ const request = react.useCallback(async (path, options) => {
12
+ const res = await fetch(`${base}${path}`, {
13
+ ...options,
14
+ headers: {
15
+ 'Content-Type': 'application/json',
16
+ Authorization: `Bearer ${tokenRef.current}`,
17
+ ...options?.headers,
18
+ },
19
+ });
20
+ if (!res.ok) {
21
+ const body = await res.json().catch(() => ({}));
22
+ throw new Error(body?.error?.message || `Request failed: ${res.status}`);
23
+ }
24
+ if (res.status === 204)
25
+ return undefined;
26
+ return res.json();
27
+ }, [base]);
28
+ const listEventTypes = react.useCallback(async () => {
29
+ const res = await request('/event-types');
30
+ return res.data;
31
+ }, [request]);
32
+ const listEndpoints = react.useCallback(async (limit = 20, offset = 0) => {
33
+ const res = await request(`/endpoints?limit=${limit}&offset=${offset}`);
34
+ return { endpoints: res.data, total: res.meta.total || 0 };
35
+ }, [request]);
36
+ const createEndpoint = react.useCallback(async (data) => {
37
+ const res = await request('/endpoints', {
38
+ method: 'POST',
39
+ body: JSON.stringify(data),
40
+ });
41
+ return res.data;
42
+ }, [request]);
43
+ const updateEndpoint = react.useCallback(async (endpointId, data) => {
44
+ const res = await request(`/endpoints/${endpointId}`, {
45
+ method: 'PUT',
46
+ body: JSON.stringify(data),
47
+ });
48
+ return res.data;
49
+ }, [request]);
50
+ const deleteEndpoint = react.useCallback(async (endpointId) => {
51
+ await request(`/endpoints/${endpointId}`, { method: 'DELETE' });
52
+ }, [request]);
53
+ const rotateSecret = react.useCallback(async (endpointId) => {
54
+ const res = await request(`/endpoints/${endpointId}/rotate-secret`, { method: 'POST' });
55
+ return res.data.secret;
56
+ }, [request]);
57
+ const listDeliveries = react.useCallback(async (endpointId, params) => {
58
+ const query = new URLSearchParams();
59
+ if (params?.limit)
60
+ query.set('limit', String(params.limit));
61
+ if (params?.offset)
62
+ query.set('offset', String(params.offset));
63
+ if (params?.status)
64
+ query.set('status', params.status);
65
+ const qs = query.toString();
66
+ const res = await request(`/endpoints/${endpointId}/deliveries${qs ? `?${qs}` : ''}`);
67
+ return { deliveries: res.data, total: res.meta.total || 0 };
68
+ }, [request]);
69
+ const getDelivery = react.useCallback(async (endpointId, deliveryId) => {
70
+ const res = await request(`/endpoints/${endpointId}/deliveries/${deliveryId}`);
71
+ return res.data;
72
+ }, [request]);
73
+ const retryDelivery = react.useCallback(async (endpointId, deliveryId) => {
74
+ await request(`/endpoints/${endpointId}/deliveries/${deliveryId}/retry`, {
75
+ method: 'POST',
76
+ });
77
+ }, [request]);
78
+ return {
79
+ listEventTypes,
80
+ listEndpoints,
81
+ createEndpoint,
82
+ updateEndpoint,
83
+ deleteEndpoint,
84
+ rotateSecret,
85
+ listDeliveries,
86
+ getDelivery,
87
+ retryDelivery,
88
+ };
89
+ }
90
+
91
+ function EndpointList({ api, eventTypes, onSelect, onCreated, onDeleted, onUpdated, onError, }) {
92
+ const [endpoints, setEndpoints] = react.useState([]);
93
+ const [isLoading, setIsLoading] = react.useState(true);
94
+ const [showCreate, setShowCreate] = react.useState(false);
95
+ const [newUrl, setNewUrl] = react.useState('');
96
+ const [newEvents, setNewEvents] = react.useState([]);
97
+ const [newDesc, setNewDesc] = react.useState('');
98
+ const [isCreating, setIsCreating] = react.useState(false);
99
+ const [createdSecret, setCreatedSecret] = react.useState(null);
100
+ const fetchEndpoints = react.useCallback(async () => {
101
+ try {
102
+ setIsLoading(true);
103
+ const result = await api.listEndpoints(100, 0);
104
+ setEndpoints(result.endpoints);
105
+ }
106
+ catch (err) {
107
+ onError?.(err instanceof Error ? err : new Error('Failed to load endpoints'));
108
+ }
109
+ finally {
110
+ setIsLoading(false);
111
+ }
112
+ }, [api, onError]);
113
+ react.useEffect(() => { fetchEndpoints(); }, [fetchEndpoints]);
114
+ const handleCreate = async () => {
115
+ if (!newUrl || newEvents.length === 0)
116
+ return;
117
+ setIsCreating(true);
118
+ try {
119
+ const endpoint = await api.createEndpoint({
120
+ url: newUrl,
121
+ events: newEvents,
122
+ description: newDesc || undefined,
123
+ });
124
+ setCreatedSecret(endpoint.secret);
125
+ setNewUrl('');
126
+ setNewEvents([]);
127
+ setNewDesc('');
128
+ await fetchEndpoints();
129
+ onCreated?.(endpoint);
130
+ }
131
+ catch (err) {
132
+ onError?.(err instanceof Error ? err : new Error('Failed to create endpoint'));
133
+ }
134
+ finally {
135
+ setIsCreating(false);
136
+ }
137
+ };
138
+ const handleDelete = async (ep) => {
139
+ try {
140
+ await api.deleteEndpoint(ep.id);
141
+ await fetchEndpoints();
142
+ onDeleted?.(ep);
143
+ }
144
+ catch (err) {
145
+ onError?.(err instanceof Error ? err : new Error('Failed to delete endpoint'));
146
+ }
147
+ };
148
+ const handleToggleStatus = async (ep) => {
149
+ const newStatus = ep.status === 'active' ? 'paused' : 'active';
150
+ try {
151
+ const updated = await api.updateEndpoint(ep.id, { status: newStatus });
152
+ await fetchEndpoints();
153
+ onUpdated?.(updated);
154
+ }
155
+ catch (err) {
156
+ onError?.(err instanceof Error ? err : new Error('Failed to update endpoint'));
157
+ }
158
+ };
159
+ const toggleEvent = (eventType) => {
160
+ setNewEvents(prev => prev.includes(eventType) ? prev.filter(e => e !== eventType) : [...prev, eventType]);
161
+ };
162
+ const statusBadgeClass = (status) => {
163
+ switch (status) {
164
+ case 'active': return 'zwp-badge zwp-badge--green';
165
+ case 'paused': return 'zwp-badge zwp-badge--yellow';
166
+ case 'disabled': return 'zwp-badge zwp-badge--red';
167
+ default: return 'zwp-badge';
168
+ }
169
+ };
170
+ if (isLoading) {
171
+ return jsxRuntime.jsx("div", { className: "zwp-loading", children: "Loading endpoints..." });
172
+ }
173
+ return (jsxRuntime.jsxs("div", { className: "zwp-endpoint-list", children: [jsxRuntime.jsxs("div", { className: "zwp-section-header", children: [jsxRuntime.jsx("h3", { className: "zwp-heading", children: "Endpoints" }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--primary", onClick: () => { setShowCreate(!showCreate); setCreatedSecret(null); }, children: showCreate ? 'Cancel' : 'Add Endpoint' })] }), createdSecret && (jsxRuntime.jsxs("div", { className: "zwp-alert zwp-alert--warning", children: [jsxRuntime.jsx("strong", { children: "Signing Secret" }), jsxRuntime.jsx("p", { children: "Store this secret securely. It will not be shown again." }), jsxRuntime.jsx("code", { className: "zwp-secret", children: createdSecret }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => { navigator.clipboard.writeText(createdSecret); }, children: "Copy" })] })), showCreate && (jsxRuntime.jsxs("div", { className: "zwp-create-form", children: [jsxRuntime.jsxs("div", { className: "zwp-field", children: [jsxRuntime.jsx("label", { className: "zwp-label", children: "URL" }), jsxRuntime.jsx("input", { className: "zwp-input", type: "url", placeholder: "https://your-app.com/webhooks", value: newUrl, onChange: e => setNewUrl(e.target.value) })] }), jsxRuntime.jsxs("div", { className: "zwp-field", children: [jsxRuntime.jsx("label", { className: "zwp-label", children: "Description (optional)" }), jsxRuntime.jsx("input", { className: "zwp-input", type: "text", placeholder: "Production endpoint", value: newDesc, onChange: e => setNewDesc(e.target.value) })] }), jsxRuntime.jsxs("div", { className: "zwp-field", children: [jsxRuntime.jsx("label", { className: "zwp-label", children: "Events" }), jsxRuntime.jsx("div", { className: "zwp-event-picker", children: eventTypes.map(et => (jsxRuntime.jsxs("label", { className: "zwp-checkbox-label", children: [jsxRuntime.jsx("input", { type: "checkbox", checked: newEvents.includes(et.event_type), onChange: () => toggleEvent(et.event_type) }), jsxRuntime.jsx("span", { className: "zwp-event-name", children: et.name }), jsxRuntime.jsx("span", { className: "zwp-event-type", children: et.event_type })] }, et.event_type))) })] }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--primary", onClick: handleCreate, disabled: isCreating || !newUrl || newEvents.length === 0, children: isCreating ? 'Creating...' : 'Create Endpoint' })] })), endpoints.length === 0 ? (jsxRuntime.jsxs("div", { className: "zwp-empty", children: [jsxRuntime.jsx("p", { children: "No endpoints configured yet." }), jsxRuntime.jsx("p", { children: "Add an endpoint to start receiving webhook deliveries." })] })) : (jsxRuntime.jsx("div", { className: "zwp-list", children: endpoints.map(ep => (jsxRuntime.jsxs("div", { className: "zwp-endpoint-card", onClick: () => onSelect(ep), children: [jsxRuntime.jsxs("div", { className: "zwp-endpoint-header", children: [jsxRuntime.jsx("code", { className: "zwp-endpoint-url", children: ep.url }), jsxRuntime.jsx("span", { className: statusBadgeClass(ep.status), children: ep.status })] }), ep.description && (jsxRuntime.jsx("p", { className: "zwp-endpoint-desc", children: ep.description })), jsxRuntime.jsxs("div", { className: "zwp-endpoint-meta", children: [jsxRuntime.jsxs("span", { children: [ep.events.length, " event", ep.events.length !== 1 ? 's' : ''] }), jsxRuntime.jsxs("span", { children: ["Created ", new Date(ep.created_at).toLocaleDateString()] })] }), jsxRuntime.jsxs("div", { className: "zwp-endpoint-actions", onClick: e => e.stopPropagation(), children: [jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm zwp-btn--ghost", onClick: () => handleToggleStatus(ep), children: ep.status === 'active' ? 'Pause' : 'Resume' }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm zwp-btn--danger", onClick: () => handleDelete(ep), children: "Delete" })] })] }, ep.id))) }))] }));
174
+ }
175
+
176
+ function EndpointDetail({ api, endpoint, onBack, onRetried, onError }) {
177
+ const [deliveries, setDeliveries] = react.useState([]);
178
+ const [total, setTotal] = react.useState(0);
179
+ const [isLoading, setIsLoading] = react.useState(true);
180
+ const [statusFilter, setStatusFilter] = react.useState('');
181
+ const [page, setPage] = react.useState(0);
182
+ const [retrying, setRetrying] = react.useState(null);
183
+ const PAGE_SIZE = 20;
184
+ const fetchDeliveries = react.useCallback(async () => {
185
+ try {
186
+ setIsLoading(true);
187
+ const result = await api.listDeliveries(endpoint.id, {
188
+ limit: PAGE_SIZE,
189
+ offset: page * PAGE_SIZE,
190
+ status: statusFilter || undefined,
191
+ });
192
+ setDeliveries(result.deliveries);
193
+ setTotal(result.total);
194
+ }
195
+ catch (err) {
196
+ onError?.(err instanceof Error ? err : new Error('Failed to load deliveries'));
197
+ }
198
+ finally {
199
+ setIsLoading(false);
200
+ }
201
+ }, [api, endpoint.id, page, statusFilter, onError]);
202
+ react.useEffect(() => { fetchDeliveries(); }, [fetchDeliveries]);
203
+ const handleRetry = async (deliveryId) => {
204
+ setRetrying(deliveryId);
205
+ try {
206
+ await api.retryDelivery(endpoint.id, deliveryId);
207
+ await fetchDeliveries();
208
+ onRetried?.(deliveryId);
209
+ }
210
+ catch (err) {
211
+ onError?.(err instanceof Error ? err : new Error('Failed to retry delivery'));
212
+ }
213
+ finally {
214
+ setRetrying(null);
215
+ }
216
+ };
217
+ const handleRotateSecret = async () => {
218
+ try {
219
+ const secret = await api.rotateSecret(endpoint.id);
220
+ alert(`New secret: ${secret}\n\nStore this securely. It will not be shown again.`);
221
+ }
222
+ catch (err) {
223
+ onError?.(err instanceof Error ? err : new Error('Failed to rotate secret'));
224
+ }
225
+ };
226
+ const statusBadgeClass = (status) => {
227
+ switch (status) {
228
+ case 'delivered': return 'zwp-badge zwp-badge--green';
229
+ case 'failed':
230
+ case 'exhausted': return 'zwp-badge zwp-badge--red';
231
+ case 'retrying':
232
+ case 'pending': return 'zwp-badge zwp-badge--yellow';
233
+ default: return 'zwp-badge';
234
+ }
235
+ };
236
+ const canRetry = (status) => status === 'failed' || status === 'exhausted';
237
+ const totalPages = Math.ceil(total / PAGE_SIZE);
238
+ return (jsxRuntime.jsxs("div", { className: "zwp-endpoint-detail", children: [jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--ghost zwp-back-btn", onClick: onBack, children: "\u2190 Back to endpoints" }), jsxRuntime.jsxs("div", { className: "zwp-detail-header", children: [jsxRuntime.jsxs("div", { children: [jsxRuntime.jsx("code", { className: "zwp-endpoint-url", children: endpoint.url }), jsxRuntime.jsxs("div", { className: "zwp-endpoint-meta", children: [jsxRuntime.jsxs("span", { children: [endpoint.events.length, " event", endpoint.events.length !== 1 ? 's' : ''] }), jsxRuntime.jsxs("span", { children: ["Status: ", endpoint.status] })] })] }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: handleRotateSecret, children: "Rotate Secret" })] }), jsxRuntime.jsxs("div", { className: "zwp-events-list", children: [jsxRuntime.jsx("h4", { className: "zwp-subheading", children: "Subscribed Events" }), jsxRuntime.jsx("div", { className: "zwp-tags", children: endpoint.events.map(e => (jsxRuntime.jsx("span", { className: "zwp-tag", children: e }, e))) })] }), jsxRuntime.jsxs("div", { className: "zwp-deliveries", children: [jsxRuntime.jsxs("div", { className: "zwp-section-header", children: [jsxRuntime.jsx("h4", { className: "zwp-subheading", children: "Delivery Log" }), jsxRuntime.jsxs("select", { className: "zwp-select", value: statusFilter, onChange: e => { setStatusFilter(e.target.value); setPage(0); }, children: [jsxRuntime.jsx("option", { value: "", children: "All statuses" }), jsxRuntime.jsx("option", { value: "delivered", children: "Delivered" }), jsxRuntime.jsx("option", { value: "failed", children: "Failed" }), jsxRuntime.jsx("option", { value: "exhausted", children: "Exhausted" }), jsxRuntime.jsx("option", { value: "retrying", children: "Retrying" }), jsxRuntime.jsx("option", { value: "pending", children: "Pending" })] })] }), isLoading ? (jsxRuntime.jsx("div", { className: "zwp-loading", children: "Loading deliveries..." })) : deliveries.length === 0 ? (jsxRuntime.jsx("div", { className: "zwp-empty", children: jsxRuntime.jsx("p", { children: "No deliveries yet." }) })) : (jsxRuntime.jsxs(jsxRuntime.Fragment, { children: [jsxRuntime.jsxs("table", { className: "zwp-table", children: [jsxRuntime.jsx("thead", { children: jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("th", { children: "Event" }), jsxRuntime.jsx("th", { children: "Status" }), jsxRuntime.jsx("th", { children: "Attempts" }), jsxRuntime.jsx("th", { children: "Response" }), jsxRuntime.jsx("th", { children: "Time" }), jsxRuntime.jsx("th", {})] }) }), jsxRuntime.jsx("tbody", { children: deliveries.map(d => (jsxRuntime.jsxs("tr", { children: [jsxRuntime.jsx("td", { children: jsxRuntime.jsx("code", { className: "zwp-event-code", children: d.event_type }) }), jsxRuntime.jsx("td", { children: jsxRuntime.jsx("span", { className: statusBadgeClass(d.status), children: d.status }) }), jsxRuntime.jsxs("td", { children: [d.attempts, "/", d.max_attempts] }), jsxRuntime.jsx("td", { children: d.last_response_status || '—' }), jsxRuntime.jsx("td", { className: "zwp-time", children: d.last_attempted_at
239
+ ? new Date(d.last_attempted_at).toLocaleString()
240
+ : new Date(d.created_at).toLocaleString() }), jsxRuntime.jsx("td", { children: canRetry(d.status) && (jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => handleRetry(d.id), disabled: retrying === d.id, children: retrying === d.id ? '...' : 'Retry' })) })] }, d.id))) })] }), totalPages > 1 && (jsxRuntime.jsxs("div", { className: "zwp-pagination", children: [jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => setPage(p => p - 1), disabled: page === 0, children: "Previous" }), jsxRuntime.jsxs("span", { className: "zwp-page-info", children: ["Page ", page + 1, " of ", totalPages] }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => setPage(p => p + 1), disabled: page >= totalPages - 1, children: "Next" })] }))] }))] })] }));
241
+ }
242
+
243
+ const PREVIEW_ENDPOINTS = [
244
+ {
245
+ id: 'preview-1',
246
+ url: 'https://api.example.com/webhooks',
247
+ description: 'Production endpoint',
248
+ events: ['order.created', 'order.updated', 'payment.completed'],
249
+ status: 'active',
250
+ consecutive_failures: 0,
251
+ created_at: new Date().toISOString(),
252
+ updated_at: new Date().toISOString(),
253
+ },
254
+ {
255
+ id: 'preview-2',
256
+ url: 'https://staging.example.com/hooks',
257
+ events: ['order.created'],
258
+ status: 'paused',
259
+ consecutive_failures: 0,
260
+ created_at: new Date(Date.now() - 86400000).toISOString(),
261
+ updated_at: new Date(Date.now() - 86400000).toISOString(),
262
+ },
263
+ ];
264
+ function PreviewEndpointList() {
265
+ return (jsxRuntime.jsxs("div", { className: "zwp-endpoint-list", children: [jsxRuntime.jsxs("div", { className: "zwp-section-header", children: [jsxRuntime.jsx("h3", { className: "zwp-heading", children: "Endpoints" }), jsxRuntime.jsx("button", { className: "zwp-btn zwp-btn--primary", disabled: true, children: "Add Endpoint" })] }), jsxRuntime.jsx("div", { className: "zwp-list", children: PREVIEW_ENDPOINTS.map(ep => (jsxRuntime.jsxs("div", { className: "zwp-endpoint-card", style: { cursor: 'default' }, children: [jsxRuntime.jsxs("div", { className: "zwp-endpoint-header", children: [jsxRuntime.jsx("code", { className: "zwp-endpoint-url", children: ep.url }), jsxRuntime.jsx("span", { className: `zwp-badge ${ep.status === 'active' ? 'zwp-badge--green' : 'zwp-badge--yellow'}`, children: ep.status })] }), ep.description && jsxRuntime.jsx("p", { className: "zwp-endpoint-desc", children: ep.description }), jsxRuntime.jsxs("div", { className: "zwp-endpoint-meta", children: [jsxRuntime.jsxs("span", { children: [ep.events.length, " event", ep.events.length !== 1 ? 's' : ''] }), jsxRuntime.jsxs("span", { children: ["Created ", new Date(ep.created_at).toLocaleDateString()] })] })] }, ep.id))) })] }));
266
+ }
267
+ function WebhookPortal({ token, baseUrl, theme, preview, onEndpointCreated, onEndpointDeleted, onEndpointUpdated, onDeliveryRetried, onError, className, }) {
268
+ const api = usePortalApi({ token, baseUrl });
269
+ const [eventTypes, setEventTypes] = react.useState([]);
270
+ const [selectedEndpoint, setSelectedEndpoint] = react.useState(null);
271
+ const [error, setError] = react.useState(null);
272
+ react.useEffect(() => {
273
+ if (preview)
274
+ return;
275
+ api.listEventTypes()
276
+ .then(setEventTypes)
277
+ .catch(err => {
278
+ const e = err instanceof Error ? err : new Error('Failed to load event types');
279
+ setError(e.message);
280
+ onError?.(e);
281
+ });
282
+ }, [api, onError, preview]);
283
+ const handleError = (err) => {
284
+ setError(err.message);
285
+ onError?.(err);
286
+ setTimeout(() => setError(null), 5000);
287
+ };
288
+ const style = {};
289
+ if (theme?.accent) {
290
+ style['--zwp-accent'] = theme.accent;
291
+ }
292
+ if (theme?.borderRadius !== undefined) {
293
+ style['--zwp-radius'] = `${theme.borderRadius}px`;
294
+ }
295
+ const themeClass = theme?.mode === 'dark' ? 'zwp-dark' : 'zwp-light';
296
+ return (jsxRuntime.jsxs("div", { className: `zwp-portal ${themeClass} ${className || ''}`, style: style, children: [error && (jsxRuntime.jsxs("div", { className: "zwp-alert zwp-alert--error", children: [error, jsxRuntime.jsx("button", { className: "zwp-alert-close", onClick: () => setError(null), children: "\u00D7" })] })), preview ? (jsxRuntime.jsx(PreviewEndpointList, {})) : selectedEndpoint ? (jsxRuntime.jsx(EndpointDetail, { api: api, endpoint: selectedEndpoint, onBack: () => setSelectedEndpoint(null), onRetried: onDeliveryRetried, onError: handleError })) : (jsxRuntime.jsx(EndpointList, { api: api, eventTypes: eventTypes, onSelect: setSelectedEndpoint, onCreated: onEndpointCreated, onDeleted: onEndpointDeleted, onUpdated: onEndpointUpdated, onError: handleError }))] }));
297
+ }
298
+
299
+ exports.WebhookPortal = WebhookPortal;
300
+ exports.usePortalApi = usePortalApi;
301
+ //# sourceMappingURL=index.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.cjs","sources":["../src/hooks/usePortalApi.ts","../src/components/EndpointList.tsx","../src/components/EndpointDetail.tsx","../src/components/WebhookPortal.tsx"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport type {\n PortalApiResponse,\n PortalEventType,\n PortalEndpoint,\n PortalEndpointWithSecret,\n PortalDelivery,\n PortalDeliveryDetail,\n} from '../types';\n\nconst DEFAULT_BASE_URL = 'https://api.zyphr.dev/v1/waas-portal';\n\ninterface UsePortalApiOptions {\n token: string;\n baseUrl?: string;\n}\n\nexport function usePortalApi({ token, baseUrl }: UsePortalApiOptions) {\n const base = baseUrl || DEFAULT_BASE_URL;\n const tokenRef = useRef(token);\n tokenRef.current = token;\n\n const request = useCallback(async <T>(path: string, options?: RequestInit): Promise<T> => {\n const res = await fetch(`${base}${path}`, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${tokenRef.current}`,\n ...options?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(body?.error?.message || `Request failed: ${res.status}`);\n }\n\n if (res.status === 204) return undefined as T;\n return res.json();\n }, [base]);\n\n const listEventTypes = useCallback(async () => {\n const res = await request<PortalApiResponse<PortalEventType[]>>('/event-types');\n return res.data;\n }, [request]);\n\n const listEndpoints = useCallback(async (limit = 20, offset = 0) => {\n const res = await request<PortalApiResponse<PortalEndpoint[]>>(\n `/endpoints?limit=${limit}&offset=${offset}`\n );\n return { endpoints: res.data, total: res.meta.total || 0 };\n }, [request]);\n\n const createEndpoint = useCallback(async (data: {\n url: string;\n events: string[];\n description?: string;\n }) => {\n const res = await request<PortalApiResponse<PortalEndpointWithSecret>>('/endpoints', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n return res.data;\n }, [request]);\n\n const updateEndpoint = useCallback(async (endpointId: string, data: {\n url?: string;\n events?: string[];\n status?: 'active' | 'paused' | 'disabled';\n description?: string;\n }) => {\n const res = await request<PortalApiResponse<PortalEndpoint>>(`/endpoints/${endpointId}`, {\n method: 'PUT',\n body: JSON.stringify(data),\n });\n return res.data;\n }, [request]);\n\n const deleteEndpoint = useCallback(async (endpointId: string) => {\n await request(`/endpoints/${endpointId}`, { method: 'DELETE' });\n }, [request]);\n\n const rotateSecret = useCallback(async (endpointId: string) => {\n const res = await request<PortalApiResponse<{ secret: string }>>(\n `/endpoints/${endpointId}/rotate-secret`,\n { method: 'POST' }\n );\n return res.data.secret;\n }, [request]);\n\n const listDeliveries = useCallback(async (endpointId: string, params?: {\n limit?: number;\n offset?: number;\n status?: string;\n }) => {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n if (params?.status) query.set('status', params.status);\n const qs = query.toString();\n\n const res = await request<PortalApiResponse<PortalDelivery[]>>(\n `/endpoints/${endpointId}/deliveries${qs ? `?${qs}` : ''}`\n );\n return { deliveries: res.data, total: res.meta.total || 0 };\n }, [request]);\n\n const getDelivery = useCallback(async (endpointId: string, deliveryId: string) => {\n const res = await request<PortalApiResponse<PortalDeliveryDetail>>(\n `/endpoints/${endpointId}/deliveries/${deliveryId}`\n );\n return res.data;\n }, [request]);\n\n const retryDelivery = useCallback(async (endpointId: string, deliveryId: string) => {\n await request(`/endpoints/${endpointId}/deliveries/${deliveryId}/retry`, {\n method: 'POST',\n });\n }, [request]);\n\n return {\n listEventTypes,\n listEndpoints,\n createEndpoint,\n updateEndpoint,\n deleteEndpoint,\n rotateSecret,\n listDeliveries,\n getDelivery,\n retryDelivery,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { PortalEndpoint, PortalEventType } from '../types';\nimport type { usePortalApi } from '../hooks/usePortalApi';\n\ninterface EndpointListProps {\n api: ReturnType<typeof usePortalApi>;\n eventTypes: PortalEventType[];\n onSelect: (endpoint: PortalEndpoint) => void;\n onCreated?: (endpoint: PortalEndpoint) => void;\n onDeleted?: (endpoint: PortalEndpoint) => void;\n onUpdated?: (endpoint: PortalEndpoint) => void;\n onError?: (error: Error) => void;\n}\n\nexport function EndpointList({\n api,\n eventTypes,\n onSelect,\n onCreated,\n onDeleted,\n onUpdated,\n onError,\n}: EndpointListProps) {\n const [endpoints, setEndpoints] = useState<PortalEndpoint[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [showCreate, setShowCreate] = useState(false);\n const [newUrl, setNewUrl] = useState('');\n const [newEvents, setNewEvents] = useState<string[]>([]);\n const [newDesc, setNewDesc] = useState('');\n const [isCreating, setIsCreating] = useState(false);\n const [createdSecret, setCreatedSecret] = useState<string | null>(null);\n\n const fetchEndpoints = useCallback(async () => {\n try {\n setIsLoading(true);\n const result = await api.listEndpoints(100, 0);\n setEndpoints(result.endpoints);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to load endpoints'));\n } finally {\n setIsLoading(false);\n }\n }, [api, onError]);\n\n useEffect(() => { fetchEndpoints(); }, [fetchEndpoints]);\n\n const handleCreate = async () => {\n if (!newUrl || newEvents.length === 0) return;\n setIsCreating(true);\n try {\n const endpoint = await api.createEndpoint({\n url: newUrl,\n events: newEvents,\n description: newDesc || undefined,\n });\n setCreatedSecret(endpoint.secret);\n setNewUrl('');\n setNewEvents([]);\n setNewDesc('');\n await fetchEndpoints();\n onCreated?.(endpoint);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to create endpoint'));\n } finally {\n setIsCreating(false);\n }\n };\n\n const handleDelete = async (ep: PortalEndpoint) => {\n try {\n await api.deleteEndpoint(ep.id);\n await fetchEndpoints();\n onDeleted?.(ep);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to delete endpoint'));\n }\n };\n\n const handleToggleStatus = async (ep: PortalEndpoint) => {\n const newStatus = ep.status === 'active' ? 'paused' : 'active';\n try {\n const updated = await api.updateEndpoint(ep.id, { status: newStatus });\n await fetchEndpoints();\n onUpdated?.(updated);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to update endpoint'));\n }\n };\n\n const toggleEvent = (eventType: string) => {\n setNewEvents(prev =>\n prev.includes(eventType) ? prev.filter(e => e !== eventType) : [...prev, eventType]\n );\n };\n\n const statusBadgeClass = (status: string) => {\n switch (status) {\n case 'active': return 'zwp-badge zwp-badge--green';\n case 'paused': return 'zwp-badge zwp-badge--yellow';\n case 'disabled': return 'zwp-badge zwp-badge--red';\n default: return 'zwp-badge';\n }\n };\n\n if (isLoading) {\n return <div className=\"zwp-loading\">Loading endpoints...</div>;\n }\n\n return (\n <div className=\"zwp-endpoint-list\">\n <div className=\"zwp-section-header\">\n <h3 className=\"zwp-heading\">Endpoints</h3>\n <button\n className=\"zwp-btn zwp-btn--primary\"\n onClick={() => { setShowCreate(!showCreate); setCreatedSecret(null); }}\n >\n {showCreate ? 'Cancel' : 'Add Endpoint'}\n </button>\n </div>\n\n {createdSecret && (\n <div className=\"zwp-alert zwp-alert--warning\">\n <strong>Signing Secret</strong>\n <p>Store this secret securely. It will not be shown again.</p>\n <code className=\"zwp-secret\">{createdSecret}</code>\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => { navigator.clipboard.writeText(createdSecret); }}\n >\n Copy\n </button>\n </div>\n )}\n\n {showCreate && (\n <div className=\"zwp-create-form\">\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">URL</label>\n <input\n className=\"zwp-input\"\n type=\"url\"\n placeholder=\"https://your-app.com/webhooks\"\n value={newUrl}\n onChange={e => setNewUrl(e.target.value)}\n />\n </div>\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">Description (optional)</label>\n <input\n className=\"zwp-input\"\n type=\"text\"\n placeholder=\"Production endpoint\"\n value={newDesc}\n onChange={e => setNewDesc(e.target.value)}\n />\n </div>\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">Events</label>\n <div className=\"zwp-event-picker\">\n {eventTypes.map(et => (\n <label key={et.event_type} className=\"zwp-checkbox-label\">\n <input\n type=\"checkbox\"\n checked={newEvents.includes(et.event_type)}\n onChange={() => toggleEvent(et.event_type)}\n />\n <span className=\"zwp-event-name\">{et.name}</span>\n <span className=\"zwp-event-type\">{et.event_type}</span>\n </label>\n ))}\n </div>\n </div>\n <button\n className=\"zwp-btn zwp-btn--primary\"\n onClick={handleCreate}\n disabled={isCreating || !newUrl || newEvents.length === 0}\n >\n {isCreating ? 'Creating...' : 'Create Endpoint'}\n </button>\n </div>\n )}\n\n {endpoints.length === 0 ? (\n <div className=\"zwp-empty\">\n <p>No endpoints configured yet.</p>\n <p>Add an endpoint to start receiving webhook deliveries.</p>\n </div>\n ) : (\n <div className=\"zwp-list\">\n {endpoints.map(ep => (\n <div key={ep.id} className=\"zwp-endpoint-card\" onClick={() => onSelect(ep)}>\n <div className=\"zwp-endpoint-header\">\n <code className=\"zwp-endpoint-url\">{ep.url}</code>\n <span className={statusBadgeClass(ep.status)}>{ep.status}</span>\n </div>\n {ep.description && (\n <p className=\"zwp-endpoint-desc\">{ep.description}</p>\n )}\n <div className=\"zwp-endpoint-meta\">\n <span>{ep.events.length} event{ep.events.length !== 1 ? 's' : ''}</span>\n <span>Created {new Date(ep.created_at).toLocaleDateString()}</span>\n </div>\n <div className=\"zwp-endpoint-actions\" onClick={e => e.stopPropagation()}>\n <button\n className=\"zwp-btn zwp-btn--sm zwp-btn--ghost\"\n onClick={() => handleToggleStatus(ep)}\n >\n {ep.status === 'active' ? 'Pause' : 'Resume'}\n </button>\n <button\n className=\"zwp-btn zwp-btn--sm zwp-btn--danger\"\n onClick={() => handleDelete(ep)}\n >\n Delete\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { PortalEndpoint, PortalDelivery } from '../types';\nimport type { usePortalApi } from '../hooks/usePortalApi';\n\ninterface EndpointDetailProps {\n api: ReturnType<typeof usePortalApi>;\n endpoint: PortalEndpoint;\n onBack: () => void;\n onRetried?: (deliveryId: string) => void;\n onError?: (error: Error) => void;\n}\n\nexport function EndpointDetail({ api, endpoint, onBack, onRetried, onError }: EndpointDetailProps) {\n const [deliveries, setDeliveries] = useState<PortalDelivery[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(true);\n const [statusFilter, setStatusFilter] = useState('');\n const [page, setPage] = useState(0);\n const [retrying, setRetrying] = useState<string | null>(null);\n const PAGE_SIZE = 20;\n\n const fetchDeliveries = useCallback(async () => {\n try {\n setIsLoading(true);\n const result = await api.listDeliveries(endpoint.id, {\n limit: PAGE_SIZE,\n offset: page * PAGE_SIZE,\n status: statusFilter || undefined,\n });\n setDeliveries(result.deliveries);\n setTotal(result.total);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to load deliveries'));\n } finally {\n setIsLoading(false);\n }\n }, [api, endpoint.id, page, statusFilter, onError]);\n\n useEffect(() => { fetchDeliveries(); }, [fetchDeliveries]);\n\n const handleRetry = async (deliveryId: string) => {\n setRetrying(deliveryId);\n try {\n await api.retryDelivery(endpoint.id, deliveryId);\n await fetchDeliveries();\n onRetried?.(deliveryId);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to retry delivery'));\n } finally {\n setRetrying(null);\n }\n };\n\n const handleRotateSecret = async () => {\n try {\n const secret = await api.rotateSecret(endpoint.id);\n alert(`New secret: ${secret}\\n\\nStore this securely. It will not be shown again.`);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to rotate secret'));\n }\n };\n\n const statusBadgeClass = (status: string) => {\n switch (status) {\n case 'delivered': return 'zwp-badge zwp-badge--green';\n case 'failed': case 'exhausted': return 'zwp-badge zwp-badge--red';\n case 'retrying': case 'pending': return 'zwp-badge zwp-badge--yellow';\n default: return 'zwp-badge';\n }\n };\n\n const canRetry = (status: string) => status === 'failed' || status === 'exhausted';\n const totalPages = Math.ceil(total / PAGE_SIZE);\n\n return (\n <div className=\"zwp-endpoint-detail\">\n <button className=\"zwp-btn zwp-btn--ghost zwp-back-btn\" onClick={onBack}>\n &larr; Back to endpoints\n </button>\n\n <div className=\"zwp-detail-header\">\n <div>\n <code className=\"zwp-endpoint-url\">{endpoint.url}</code>\n <div className=\"zwp-endpoint-meta\">\n <span>{endpoint.events.length} event{endpoint.events.length !== 1 ? 's' : ''}</span>\n <span>Status: {endpoint.status}</span>\n </div>\n </div>\n <button className=\"zwp-btn zwp-btn--sm\" onClick={handleRotateSecret}>\n Rotate Secret\n </button>\n </div>\n\n <div className=\"zwp-events-list\">\n <h4 className=\"zwp-subheading\">Subscribed Events</h4>\n <div className=\"zwp-tags\">\n {endpoint.events.map(e => (\n <span key={e} className=\"zwp-tag\">{e}</span>\n ))}\n </div>\n </div>\n\n <div className=\"zwp-deliveries\">\n <div className=\"zwp-section-header\">\n <h4 className=\"zwp-subheading\">Delivery Log</h4>\n <select\n className=\"zwp-select\"\n value={statusFilter}\n onChange={e => { setStatusFilter(e.target.value); setPage(0); }}\n >\n <option value=\"\">All statuses</option>\n <option value=\"delivered\">Delivered</option>\n <option value=\"failed\">Failed</option>\n <option value=\"exhausted\">Exhausted</option>\n <option value=\"retrying\">Retrying</option>\n <option value=\"pending\">Pending</option>\n </select>\n </div>\n\n {isLoading ? (\n <div className=\"zwp-loading\">Loading deliveries...</div>\n ) : deliveries.length === 0 ? (\n <div className=\"zwp-empty\">\n <p>No deliveries yet.</p>\n </div>\n ) : (\n <>\n <table className=\"zwp-table\">\n <thead>\n <tr>\n <th>Event</th>\n <th>Status</th>\n <th>Attempts</th>\n <th>Response</th>\n <th>Time</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n {deliveries.map(d => (\n <tr key={d.id}>\n <td><code className=\"zwp-event-code\">{d.event_type}</code></td>\n <td><span className={statusBadgeClass(d.status)}>{d.status}</span></td>\n <td>{d.attempts}/{d.max_attempts}</td>\n <td>{d.last_response_status || '—'}</td>\n <td className=\"zwp-time\">\n {d.last_attempted_at\n ? new Date(d.last_attempted_at).toLocaleString()\n : new Date(d.created_at).toLocaleString()}\n </td>\n <td>\n {canRetry(d.status) && (\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => handleRetry(d.id)}\n disabled={retrying === d.id}\n >\n {retrying === d.id ? '...' : 'Retry'}\n </button>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n\n {totalPages > 1 && (\n <div className=\"zwp-pagination\">\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => setPage(p => p - 1)}\n disabled={page === 0}\n >\n Previous\n </button>\n <span className=\"zwp-page-info\">\n Page {page + 1} of {totalPages}\n </span>\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => setPage(p => p + 1)}\n disabled={page >= totalPages - 1}\n >\n Next\n </button>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport type { WebhookPortalProps, PortalEndpoint, PortalEventType } from '../types';\nimport { usePortalApi } from '../hooks/usePortalApi';\nimport { EndpointList } from './EndpointList';\nimport { EndpointDetail } from './EndpointDetail';\n\nconst PREVIEW_ENDPOINTS: PortalEndpoint[] = [\n {\n id: 'preview-1',\n url: 'https://api.example.com/webhooks',\n description: 'Production endpoint',\n events: ['order.created', 'order.updated', 'payment.completed'],\n status: 'active',\n consecutive_failures: 0,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n },\n {\n id: 'preview-2',\n url: 'https://staging.example.com/hooks',\n events: ['order.created'],\n status: 'paused',\n consecutive_failures: 0,\n created_at: new Date(Date.now() - 86400000).toISOString(),\n updated_at: new Date(Date.now() - 86400000).toISOString(),\n },\n];\n\nfunction PreviewEndpointList() {\n return (\n <div className=\"zwp-endpoint-list\">\n <div className=\"zwp-section-header\">\n <h3 className=\"zwp-heading\">Endpoints</h3>\n <button className=\"zwp-btn zwp-btn--primary\" disabled>Add Endpoint</button>\n </div>\n <div className=\"zwp-list\">\n {PREVIEW_ENDPOINTS.map(ep => (\n <div key={ep.id} className=\"zwp-endpoint-card\" style={{ cursor: 'default' }}>\n <div className=\"zwp-endpoint-header\">\n <code className=\"zwp-endpoint-url\">{ep.url}</code>\n <span className={`zwp-badge ${ep.status === 'active' ? 'zwp-badge--green' : 'zwp-badge--yellow'}`}>\n {ep.status}\n </span>\n </div>\n {ep.description && <p className=\"zwp-endpoint-desc\">{ep.description}</p>}\n <div className=\"zwp-endpoint-meta\">\n <span>{ep.events.length} event{ep.events.length !== 1 ? 's' : ''}</span>\n <span>Created {new Date(ep.created_at).toLocaleDateString()}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport function WebhookPortal({\n token,\n baseUrl,\n theme,\n preview,\n onEndpointCreated,\n onEndpointDeleted,\n onEndpointUpdated,\n onDeliveryRetried,\n onError,\n className,\n}: WebhookPortalProps) {\n const api = usePortalApi({ token, baseUrl });\n const [eventTypes, setEventTypes] = useState<PortalEventType[]>([]);\n const [selectedEndpoint, setSelectedEndpoint] = useState<PortalEndpoint | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (preview) return;\n api.listEventTypes()\n .then(setEventTypes)\n .catch(err => {\n const e = err instanceof Error ? err : new Error('Failed to load event types');\n setError(e.message);\n onError?.(e);\n });\n }, [api, onError, preview]);\n\n const handleError = (err: Error) => {\n setError(err.message);\n onError?.(err);\n setTimeout(() => setError(null), 5000);\n };\n\n const style: Record<string, string> = {};\n if (theme?.accent) {\n style['--zwp-accent'] = theme.accent;\n }\n if (theme?.borderRadius !== undefined) {\n style['--zwp-radius'] = `${theme.borderRadius}px`;\n }\n\n const themeClass = theme?.mode === 'dark' ? 'zwp-dark' : 'zwp-light';\n\n return (\n <div\n className={`zwp-portal ${themeClass} ${className || ''}`}\n style={style}\n >\n {error && (\n <div className=\"zwp-alert zwp-alert--error\">\n {error}\n <button className=\"zwp-alert-close\" onClick={() => setError(null)}>&times;</button>\n </div>\n )}\n\n {preview ? (\n <PreviewEndpointList />\n ) : selectedEndpoint ? (\n <EndpointDetail\n api={api}\n endpoint={selectedEndpoint}\n onBack={() => setSelectedEndpoint(null)}\n onRetried={onDeliveryRetried}\n onError={handleError}\n />\n ) : (\n <EndpointList\n api={api}\n eventTypes={eventTypes}\n onSelect={setSelectedEndpoint}\n onCreated={onEndpointCreated}\n onDeleted={onEndpointDeleted}\n onUpdated={onEndpointUpdated}\n onError={handleError}\n />\n )}\n </div>\n );\n}\n"],"names":["useRef","useCallback","useState","useEffect","_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -0,0 +1,107 @@
1
+ import * as react_jsx_runtime from 'react/jsx-runtime';
2
+
3
+ interface PortalEventType {
4
+ event_type: string;
5
+ name: string;
6
+ description?: string;
7
+ category?: string;
8
+ example_payload?: Record<string, unknown>;
9
+ }
10
+ interface PortalEndpoint {
11
+ id: string;
12
+ url: string;
13
+ description?: string;
14
+ events: string[];
15
+ status: 'active' | 'paused' | 'disabled';
16
+ retry_policy?: {
17
+ max_attempts?: number;
18
+ intervals?: number[];
19
+ };
20
+ consecutive_failures?: number;
21
+ last_failure_at?: string;
22
+ disabled_at?: string;
23
+ disabled_reason?: string;
24
+ created_at: string;
25
+ updated_at: string;
26
+ }
27
+ interface PortalEndpointWithSecret extends PortalEndpoint {
28
+ secret: string;
29
+ }
30
+ interface PortalDelivery {
31
+ id: string;
32
+ event_id: string;
33
+ event_type: string;
34
+ status: 'pending' | 'delivering' | 'delivered' | 'failed' | 'retrying' | 'exhausted';
35
+ attempts: number;
36
+ max_attempts: number;
37
+ last_response_status?: number;
38
+ latency_ms?: number;
39
+ last_error?: string;
40
+ first_attempted_at?: string;
41
+ last_attempted_at?: string;
42
+ completed_at?: string;
43
+ created_at: string;
44
+ }
45
+ interface PortalDeliveryDetail extends PortalDelivery {
46
+ payload?: Record<string, unknown>;
47
+ last_response_body?: string;
48
+ }
49
+ interface PortalTheme {
50
+ mode?: 'light' | 'dark';
51
+ accent?: string;
52
+ borderRadius?: number;
53
+ }
54
+ interface WebhookPortalProps {
55
+ token: string;
56
+ baseUrl?: string;
57
+ theme?: PortalTheme;
58
+ locale?: string;
59
+ /** Render with mock data and no API calls. Useful for previewing theme/accent. */
60
+ preview?: boolean;
61
+ onEndpointCreated?: (endpoint: PortalEndpoint) => void;
62
+ onEndpointDeleted?: (endpoint: PortalEndpoint) => void;
63
+ onEndpointUpdated?: (endpoint: PortalEndpoint) => void;
64
+ onDeliveryRetried?: (deliveryId: string) => void;
65
+ onError?: (error: Error) => void;
66
+ className?: string;
67
+ }
68
+
69
+ declare function WebhookPortal({ token, baseUrl, theme, preview, onEndpointCreated, onEndpointDeleted, onEndpointUpdated, onDeliveryRetried, onError, className, }: WebhookPortalProps): react_jsx_runtime.JSX.Element;
70
+
71
+ interface UsePortalApiOptions {
72
+ token: string;
73
+ baseUrl?: string;
74
+ }
75
+ declare function usePortalApi({ token, baseUrl }: UsePortalApiOptions): {
76
+ listEventTypes: () => Promise<PortalEventType[]>;
77
+ listEndpoints: (limit?: number, offset?: number) => Promise<{
78
+ endpoints: PortalEndpoint[];
79
+ total: number;
80
+ }>;
81
+ createEndpoint: (data: {
82
+ url: string;
83
+ events: string[];
84
+ description?: string;
85
+ }) => Promise<PortalEndpointWithSecret>;
86
+ updateEndpoint: (endpointId: string, data: {
87
+ url?: string;
88
+ events?: string[];
89
+ status?: "active" | "paused" | "disabled";
90
+ description?: string;
91
+ }) => Promise<PortalEndpoint>;
92
+ deleteEndpoint: (endpointId: string) => Promise<void>;
93
+ rotateSecret: (endpointId: string) => Promise<string>;
94
+ listDeliveries: (endpointId: string, params?: {
95
+ limit?: number;
96
+ offset?: number;
97
+ status?: string;
98
+ }) => Promise<{
99
+ deliveries: PortalDelivery[];
100
+ total: number;
101
+ }>;
102
+ getDelivery: (endpointId: string, deliveryId: string) => Promise<PortalDeliveryDetail>;
103
+ retryDelivery: (endpointId: string, deliveryId: string) => Promise<void>;
104
+ };
105
+
106
+ export { WebhookPortal, usePortalApi };
107
+ export type { PortalDelivery, PortalDeliveryDetail, PortalEndpoint, PortalEndpointWithSecret, PortalEventType, PortalTheme, WebhookPortalProps };
package/dist/index.js ADDED
@@ -0,0 +1,298 @@
1
+ import { jsx, jsxs, Fragment } from 'react/jsx-runtime';
2
+ import { useRef, useCallback, useState, useEffect } from 'react';
3
+
4
+ const DEFAULT_BASE_URL = 'https://api.zyphr.dev/v1/waas-portal';
5
+ function usePortalApi({ token, baseUrl }) {
6
+ const base = baseUrl || DEFAULT_BASE_URL;
7
+ const tokenRef = useRef(token);
8
+ tokenRef.current = token;
9
+ const request = useCallback(async (path, options) => {
10
+ const res = await fetch(`${base}${path}`, {
11
+ ...options,
12
+ headers: {
13
+ 'Content-Type': 'application/json',
14
+ Authorization: `Bearer ${tokenRef.current}`,
15
+ ...options?.headers,
16
+ },
17
+ });
18
+ if (!res.ok) {
19
+ const body = await res.json().catch(() => ({}));
20
+ throw new Error(body?.error?.message || `Request failed: ${res.status}`);
21
+ }
22
+ if (res.status === 204)
23
+ return undefined;
24
+ return res.json();
25
+ }, [base]);
26
+ const listEventTypes = useCallback(async () => {
27
+ const res = await request('/event-types');
28
+ return res.data;
29
+ }, [request]);
30
+ const listEndpoints = useCallback(async (limit = 20, offset = 0) => {
31
+ const res = await request(`/endpoints?limit=${limit}&offset=${offset}`);
32
+ return { endpoints: res.data, total: res.meta.total || 0 };
33
+ }, [request]);
34
+ const createEndpoint = useCallback(async (data) => {
35
+ const res = await request('/endpoints', {
36
+ method: 'POST',
37
+ body: JSON.stringify(data),
38
+ });
39
+ return res.data;
40
+ }, [request]);
41
+ const updateEndpoint = useCallback(async (endpointId, data) => {
42
+ const res = await request(`/endpoints/${endpointId}`, {
43
+ method: 'PUT',
44
+ body: JSON.stringify(data),
45
+ });
46
+ return res.data;
47
+ }, [request]);
48
+ const deleteEndpoint = useCallback(async (endpointId) => {
49
+ await request(`/endpoints/${endpointId}`, { method: 'DELETE' });
50
+ }, [request]);
51
+ const rotateSecret = useCallback(async (endpointId) => {
52
+ const res = await request(`/endpoints/${endpointId}/rotate-secret`, { method: 'POST' });
53
+ return res.data.secret;
54
+ }, [request]);
55
+ const listDeliveries = useCallback(async (endpointId, params) => {
56
+ const query = new URLSearchParams();
57
+ if (params?.limit)
58
+ query.set('limit', String(params.limit));
59
+ if (params?.offset)
60
+ query.set('offset', String(params.offset));
61
+ if (params?.status)
62
+ query.set('status', params.status);
63
+ const qs = query.toString();
64
+ const res = await request(`/endpoints/${endpointId}/deliveries${qs ? `?${qs}` : ''}`);
65
+ return { deliveries: res.data, total: res.meta.total || 0 };
66
+ }, [request]);
67
+ const getDelivery = useCallback(async (endpointId, deliveryId) => {
68
+ const res = await request(`/endpoints/${endpointId}/deliveries/${deliveryId}`);
69
+ return res.data;
70
+ }, [request]);
71
+ const retryDelivery = useCallback(async (endpointId, deliveryId) => {
72
+ await request(`/endpoints/${endpointId}/deliveries/${deliveryId}/retry`, {
73
+ method: 'POST',
74
+ });
75
+ }, [request]);
76
+ return {
77
+ listEventTypes,
78
+ listEndpoints,
79
+ createEndpoint,
80
+ updateEndpoint,
81
+ deleteEndpoint,
82
+ rotateSecret,
83
+ listDeliveries,
84
+ getDelivery,
85
+ retryDelivery,
86
+ };
87
+ }
88
+
89
+ function EndpointList({ api, eventTypes, onSelect, onCreated, onDeleted, onUpdated, onError, }) {
90
+ const [endpoints, setEndpoints] = useState([]);
91
+ const [isLoading, setIsLoading] = useState(true);
92
+ const [showCreate, setShowCreate] = useState(false);
93
+ const [newUrl, setNewUrl] = useState('');
94
+ const [newEvents, setNewEvents] = useState([]);
95
+ const [newDesc, setNewDesc] = useState('');
96
+ const [isCreating, setIsCreating] = useState(false);
97
+ const [createdSecret, setCreatedSecret] = useState(null);
98
+ const fetchEndpoints = useCallback(async () => {
99
+ try {
100
+ setIsLoading(true);
101
+ const result = await api.listEndpoints(100, 0);
102
+ setEndpoints(result.endpoints);
103
+ }
104
+ catch (err) {
105
+ onError?.(err instanceof Error ? err : new Error('Failed to load endpoints'));
106
+ }
107
+ finally {
108
+ setIsLoading(false);
109
+ }
110
+ }, [api, onError]);
111
+ useEffect(() => { fetchEndpoints(); }, [fetchEndpoints]);
112
+ const handleCreate = async () => {
113
+ if (!newUrl || newEvents.length === 0)
114
+ return;
115
+ setIsCreating(true);
116
+ try {
117
+ const endpoint = await api.createEndpoint({
118
+ url: newUrl,
119
+ events: newEvents,
120
+ description: newDesc || undefined,
121
+ });
122
+ setCreatedSecret(endpoint.secret);
123
+ setNewUrl('');
124
+ setNewEvents([]);
125
+ setNewDesc('');
126
+ await fetchEndpoints();
127
+ onCreated?.(endpoint);
128
+ }
129
+ catch (err) {
130
+ onError?.(err instanceof Error ? err : new Error('Failed to create endpoint'));
131
+ }
132
+ finally {
133
+ setIsCreating(false);
134
+ }
135
+ };
136
+ const handleDelete = async (ep) => {
137
+ try {
138
+ await api.deleteEndpoint(ep.id);
139
+ await fetchEndpoints();
140
+ onDeleted?.(ep);
141
+ }
142
+ catch (err) {
143
+ onError?.(err instanceof Error ? err : new Error('Failed to delete endpoint'));
144
+ }
145
+ };
146
+ const handleToggleStatus = async (ep) => {
147
+ const newStatus = ep.status === 'active' ? 'paused' : 'active';
148
+ try {
149
+ const updated = await api.updateEndpoint(ep.id, { status: newStatus });
150
+ await fetchEndpoints();
151
+ onUpdated?.(updated);
152
+ }
153
+ catch (err) {
154
+ onError?.(err instanceof Error ? err : new Error('Failed to update endpoint'));
155
+ }
156
+ };
157
+ const toggleEvent = (eventType) => {
158
+ setNewEvents(prev => prev.includes(eventType) ? prev.filter(e => e !== eventType) : [...prev, eventType]);
159
+ };
160
+ const statusBadgeClass = (status) => {
161
+ switch (status) {
162
+ case 'active': return 'zwp-badge zwp-badge--green';
163
+ case 'paused': return 'zwp-badge zwp-badge--yellow';
164
+ case 'disabled': return 'zwp-badge zwp-badge--red';
165
+ default: return 'zwp-badge';
166
+ }
167
+ };
168
+ if (isLoading) {
169
+ return jsx("div", { className: "zwp-loading", children: "Loading endpoints..." });
170
+ }
171
+ return (jsxs("div", { className: "zwp-endpoint-list", children: [jsxs("div", { className: "zwp-section-header", children: [jsx("h3", { className: "zwp-heading", children: "Endpoints" }), jsx("button", { className: "zwp-btn zwp-btn--primary", onClick: () => { setShowCreate(!showCreate); setCreatedSecret(null); }, children: showCreate ? 'Cancel' : 'Add Endpoint' })] }), createdSecret && (jsxs("div", { className: "zwp-alert zwp-alert--warning", children: [jsx("strong", { children: "Signing Secret" }), jsx("p", { children: "Store this secret securely. It will not be shown again." }), jsx("code", { className: "zwp-secret", children: createdSecret }), jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => { navigator.clipboard.writeText(createdSecret); }, children: "Copy" })] })), showCreate && (jsxs("div", { className: "zwp-create-form", children: [jsxs("div", { className: "zwp-field", children: [jsx("label", { className: "zwp-label", children: "URL" }), jsx("input", { className: "zwp-input", type: "url", placeholder: "https://your-app.com/webhooks", value: newUrl, onChange: e => setNewUrl(e.target.value) })] }), jsxs("div", { className: "zwp-field", children: [jsx("label", { className: "zwp-label", children: "Description (optional)" }), jsx("input", { className: "zwp-input", type: "text", placeholder: "Production endpoint", value: newDesc, onChange: e => setNewDesc(e.target.value) })] }), jsxs("div", { className: "zwp-field", children: [jsx("label", { className: "zwp-label", children: "Events" }), jsx("div", { className: "zwp-event-picker", children: eventTypes.map(et => (jsxs("label", { className: "zwp-checkbox-label", children: [jsx("input", { type: "checkbox", checked: newEvents.includes(et.event_type), onChange: () => toggleEvent(et.event_type) }), jsx("span", { className: "zwp-event-name", children: et.name }), jsx("span", { className: "zwp-event-type", children: et.event_type })] }, et.event_type))) })] }), jsx("button", { className: "zwp-btn zwp-btn--primary", onClick: handleCreate, disabled: isCreating || !newUrl || newEvents.length === 0, children: isCreating ? 'Creating...' : 'Create Endpoint' })] })), endpoints.length === 0 ? (jsxs("div", { className: "zwp-empty", children: [jsx("p", { children: "No endpoints configured yet." }), jsx("p", { children: "Add an endpoint to start receiving webhook deliveries." })] })) : (jsx("div", { className: "zwp-list", children: endpoints.map(ep => (jsxs("div", { className: "zwp-endpoint-card", onClick: () => onSelect(ep), children: [jsxs("div", { className: "zwp-endpoint-header", children: [jsx("code", { className: "zwp-endpoint-url", children: ep.url }), jsx("span", { className: statusBadgeClass(ep.status), children: ep.status })] }), ep.description && (jsx("p", { className: "zwp-endpoint-desc", children: ep.description })), jsxs("div", { className: "zwp-endpoint-meta", children: [jsxs("span", { children: [ep.events.length, " event", ep.events.length !== 1 ? 's' : ''] }), jsxs("span", { children: ["Created ", new Date(ep.created_at).toLocaleDateString()] })] }), jsxs("div", { className: "zwp-endpoint-actions", onClick: e => e.stopPropagation(), children: [jsx("button", { className: "zwp-btn zwp-btn--sm zwp-btn--ghost", onClick: () => handleToggleStatus(ep), children: ep.status === 'active' ? 'Pause' : 'Resume' }), jsx("button", { className: "zwp-btn zwp-btn--sm zwp-btn--danger", onClick: () => handleDelete(ep), children: "Delete" })] })] }, ep.id))) }))] }));
172
+ }
173
+
174
+ function EndpointDetail({ api, endpoint, onBack, onRetried, onError }) {
175
+ const [deliveries, setDeliveries] = useState([]);
176
+ const [total, setTotal] = useState(0);
177
+ const [isLoading, setIsLoading] = useState(true);
178
+ const [statusFilter, setStatusFilter] = useState('');
179
+ const [page, setPage] = useState(0);
180
+ const [retrying, setRetrying] = useState(null);
181
+ const PAGE_SIZE = 20;
182
+ const fetchDeliveries = useCallback(async () => {
183
+ try {
184
+ setIsLoading(true);
185
+ const result = await api.listDeliveries(endpoint.id, {
186
+ limit: PAGE_SIZE,
187
+ offset: page * PAGE_SIZE,
188
+ status: statusFilter || undefined,
189
+ });
190
+ setDeliveries(result.deliveries);
191
+ setTotal(result.total);
192
+ }
193
+ catch (err) {
194
+ onError?.(err instanceof Error ? err : new Error('Failed to load deliveries'));
195
+ }
196
+ finally {
197
+ setIsLoading(false);
198
+ }
199
+ }, [api, endpoint.id, page, statusFilter, onError]);
200
+ useEffect(() => { fetchDeliveries(); }, [fetchDeliveries]);
201
+ const handleRetry = async (deliveryId) => {
202
+ setRetrying(deliveryId);
203
+ try {
204
+ await api.retryDelivery(endpoint.id, deliveryId);
205
+ await fetchDeliveries();
206
+ onRetried?.(deliveryId);
207
+ }
208
+ catch (err) {
209
+ onError?.(err instanceof Error ? err : new Error('Failed to retry delivery'));
210
+ }
211
+ finally {
212
+ setRetrying(null);
213
+ }
214
+ };
215
+ const handleRotateSecret = async () => {
216
+ try {
217
+ const secret = await api.rotateSecret(endpoint.id);
218
+ alert(`New secret: ${secret}\n\nStore this securely. It will not be shown again.`);
219
+ }
220
+ catch (err) {
221
+ onError?.(err instanceof Error ? err : new Error('Failed to rotate secret'));
222
+ }
223
+ };
224
+ const statusBadgeClass = (status) => {
225
+ switch (status) {
226
+ case 'delivered': return 'zwp-badge zwp-badge--green';
227
+ case 'failed':
228
+ case 'exhausted': return 'zwp-badge zwp-badge--red';
229
+ case 'retrying':
230
+ case 'pending': return 'zwp-badge zwp-badge--yellow';
231
+ default: return 'zwp-badge';
232
+ }
233
+ };
234
+ const canRetry = (status) => status === 'failed' || status === 'exhausted';
235
+ const totalPages = Math.ceil(total / PAGE_SIZE);
236
+ return (jsxs("div", { className: "zwp-endpoint-detail", children: [jsx("button", { className: "zwp-btn zwp-btn--ghost zwp-back-btn", onClick: onBack, children: "\u2190 Back to endpoints" }), jsxs("div", { className: "zwp-detail-header", children: [jsxs("div", { children: [jsx("code", { className: "zwp-endpoint-url", children: endpoint.url }), jsxs("div", { className: "zwp-endpoint-meta", children: [jsxs("span", { children: [endpoint.events.length, " event", endpoint.events.length !== 1 ? 's' : ''] }), jsxs("span", { children: ["Status: ", endpoint.status] })] })] }), jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: handleRotateSecret, children: "Rotate Secret" })] }), jsxs("div", { className: "zwp-events-list", children: [jsx("h4", { className: "zwp-subheading", children: "Subscribed Events" }), jsx("div", { className: "zwp-tags", children: endpoint.events.map(e => (jsx("span", { className: "zwp-tag", children: e }, e))) })] }), jsxs("div", { className: "zwp-deliveries", children: [jsxs("div", { className: "zwp-section-header", children: [jsx("h4", { className: "zwp-subheading", children: "Delivery Log" }), jsxs("select", { className: "zwp-select", value: statusFilter, onChange: e => { setStatusFilter(e.target.value); setPage(0); }, children: [jsx("option", { value: "", children: "All statuses" }), jsx("option", { value: "delivered", children: "Delivered" }), jsx("option", { value: "failed", children: "Failed" }), jsx("option", { value: "exhausted", children: "Exhausted" }), jsx("option", { value: "retrying", children: "Retrying" }), jsx("option", { value: "pending", children: "Pending" })] })] }), isLoading ? (jsx("div", { className: "zwp-loading", children: "Loading deliveries..." })) : deliveries.length === 0 ? (jsx("div", { className: "zwp-empty", children: jsx("p", { children: "No deliveries yet." }) })) : (jsxs(Fragment, { children: [jsxs("table", { className: "zwp-table", children: [jsx("thead", { children: jsxs("tr", { children: [jsx("th", { children: "Event" }), jsx("th", { children: "Status" }), jsx("th", { children: "Attempts" }), jsx("th", { children: "Response" }), jsx("th", { children: "Time" }), jsx("th", {})] }) }), jsx("tbody", { children: deliveries.map(d => (jsxs("tr", { children: [jsx("td", { children: jsx("code", { className: "zwp-event-code", children: d.event_type }) }), jsx("td", { children: jsx("span", { className: statusBadgeClass(d.status), children: d.status }) }), jsxs("td", { children: [d.attempts, "/", d.max_attempts] }), jsx("td", { children: d.last_response_status || '—' }), jsx("td", { className: "zwp-time", children: d.last_attempted_at
237
+ ? new Date(d.last_attempted_at).toLocaleString()
238
+ : new Date(d.created_at).toLocaleString() }), jsx("td", { children: canRetry(d.status) && (jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => handleRetry(d.id), disabled: retrying === d.id, children: retrying === d.id ? '...' : 'Retry' })) })] }, d.id))) })] }), totalPages > 1 && (jsxs("div", { className: "zwp-pagination", children: [jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => setPage(p => p - 1), disabled: page === 0, children: "Previous" }), jsxs("span", { className: "zwp-page-info", children: ["Page ", page + 1, " of ", totalPages] }), jsx("button", { className: "zwp-btn zwp-btn--sm", onClick: () => setPage(p => p + 1), disabled: page >= totalPages - 1, children: "Next" })] }))] }))] })] }));
239
+ }
240
+
241
+ const PREVIEW_ENDPOINTS = [
242
+ {
243
+ id: 'preview-1',
244
+ url: 'https://api.example.com/webhooks',
245
+ description: 'Production endpoint',
246
+ events: ['order.created', 'order.updated', 'payment.completed'],
247
+ status: 'active',
248
+ consecutive_failures: 0,
249
+ created_at: new Date().toISOString(),
250
+ updated_at: new Date().toISOString(),
251
+ },
252
+ {
253
+ id: 'preview-2',
254
+ url: 'https://staging.example.com/hooks',
255
+ events: ['order.created'],
256
+ status: 'paused',
257
+ consecutive_failures: 0,
258
+ created_at: new Date(Date.now() - 86400000).toISOString(),
259
+ updated_at: new Date(Date.now() - 86400000).toISOString(),
260
+ },
261
+ ];
262
+ function PreviewEndpointList() {
263
+ return (jsxs("div", { className: "zwp-endpoint-list", children: [jsxs("div", { className: "zwp-section-header", children: [jsx("h3", { className: "zwp-heading", children: "Endpoints" }), jsx("button", { className: "zwp-btn zwp-btn--primary", disabled: true, children: "Add Endpoint" })] }), jsx("div", { className: "zwp-list", children: PREVIEW_ENDPOINTS.map(ep => (jsxs("div", { className: "zwp-endpoint-card", style: { cursor: 'default' }, children: [jsxs("div", { className: "zwp-endpoint-header", children: [jsx("code", { className: "zwp-endpoint-url", children: ep.url }), jsx("span", { className: `zwp-badge ${ep.status === 'active' ? 'zwp-badge--green' : 'zwp-badge--yellow'}`, children: ep.status })] }), ep.description && jsx("p", { className: "zwp-endpoint-desc", children: ep.description }), jsxs("div", { className: "zwp-endpoint-meta", children: [jsxs("span", { children: [ep.events.length, " event", ep.events.length !== 1 ? 's' : ''] }), jsxs("span", { children: ["Created ", new Date(ep.created_at).toLocaleDateString()] })] })] }, ep.id))) })] }));
264
+ }
265
+ function WebhookPortal({ token, baseUrl, theme, preview, onEndpointCreated, onEndpointDeleted, onEndpointUpdated, onDeliveryRetried, onError, className, }) {
266
+ const api = usePortalApi({ token, baseUrl });
267
+ const [eventTypes, setEventTypes] = useState([]);
268
+ const [selectedEndpoint, setSelectedEndpoint] = useState(null);
269
+ const [error, setError] = useState(null);
270
+ useEffect(() => {
271
+ if (preview)
272
+ return;
273
+ api.listEventTypes()
274
+ .then(setEventTypes)
275
+ .catch(err => {
276
+ const e = err instanceof Error ? err : new Error('Failed to load event types');
277
+ setError(e.message);
278
+ onError?.(e);
279
+ });
280
+ }, [api, onError, preview]);
281
+ const handleError = (err) => {
282
+ setError(err.message);
283
+ onError?.(err);
284
+ setTimeout(() => setError(null), 5000);
285
+ };
286
+ const style = {};
287
+ if (theme?.accent) {
288
+ style['--zwp-accent'] = theme.accent;
289
+ }
290
+ if (theme?.borderRadius !== undefined) {
291
+ style['--zwp-radius'] = `${theme.borderRadius}px`;
292
+ }
293
+ const themeClass = theme?.mode === 'dark' ? 'zwp-dark' : 'zwp-light';
294
+ return (jsxs("div", { className: `zwp-portal ${themeClass} ${className || ''}`, style: style, children: [error && (jsxs("div", { className: "zwp-alert zwp-alert--error", children: [error, jsx("button", { className: "zwp-alert-close", onClick: () => setError(null), children: "\u00D7" })] })), preview ? (jsx(PreviewEndpointList, {})) : selectedEndpoint ? (jsx(EndpointDetail, { api: api, endpoint: selectedEndpoint, onBack: () => setSelectedEndpoint(null), onRetried: onDeliveryRetried, onError: handleError })) : (jsx(EndpointList, { api: api, eventTypes: eventTypes, onSelect: setSelectedEndpoint, onCreated: onEndpointCreated, onDeleted: onEndpointDeleted, onUpdated: onEndpointUpdated, onError: handleError }))] }));
295
+ }
296
+
297
+ export { WebhookPortal, usePortalApi };
298
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sources":["../src/hooks/usePortalApi.ts","../src/components/EndpointList.tsx","../src/components/EndpointDetail.tsx","../src/components/WebhookPortal.tsx"],"sourcesContent":["import { useCallback, useRef } from 'react';\nimport type {\n PortalApiResponse,\n PortalEventType,\n PortalEndpoint,\n PortalEndpointWithSecret,\n PortalDelivery,\n PortalDeliveryDetail,\n} from '../types';\n\nconst DEFAULT_BASE_URL = 'https://api.zyphr.dev/v1/waas-portal';\n\ninterface UsePortalApiOptions {\n token: string;\n baseUrl?: string;\n}\n\nexport function usePortalApi({ token, baseUrl }: UsePortalApiOptions) {\n const base = baseUrl || DEFAULT_BASE_URL;\n const tokenRef = useRef(token);\n tokenRef.current = token;\n\n const request = useCallback(async <T>(path: string, options?: RequestInit): Promise<T> => {\n const res = await fetch(`${base}${path}`, {\n ...options,\n headers: {\n 'Content-Type': 'application/json',\n Authorization: `Bearer ${tokenRef.current}`,\n ...options?.headers,\n },\n });\n\n if (!res.ok) {\n const body = await res.json().catch(() => ({}));\n throw new Error(body?.error?.message || `Request failed: ${res.status}`);\n }\n\n if (res.status === 204) return undefined as T;\n return res.json();\n }, [base]);\n\n const listEventTypes = useCallback(async () => {\n const res = await request<PortalApiResponse<PortalEventType[]>>('/event-types');\n return res.data;\n }, [request]);\n\n const listEndpoints = useCallback(async (limit = 20, offset = 0) => {\n const res = await request<PortalApiResponse<PortalEndpoint[]>>(\n `/endpoints?limit=${limit}&offset=${offset}`\n );\n return { endpoints: res.data, total: res.meta.total || 0 };\n }, [request]);\n\n const createEndpoint = useCallback(async (data: {\n url: string;\n events: string[];\n description?: string;\n }) => {\n const res = await request<PortalApiResponse<PortalEndpointWithSecret>>('/endpoints', {\n method: 'POST',\n body: JSON.stringify(data),\n });\n return res.data;\n }, [request]);\n\n const updateEndpoint = useCallback(async (endpointId: string, data: {\n url?: string;\n events?: string[];\n status?: 'active' | 'paused' | 'disabled';\n description?: string;\n }) => {\n const res = await request<PortalApiResponse<PortalEndpoint>>(`/endpoints/${endpointId}`, {\n method: 'PUT',\n body: JSON.stringify(data),\n });\n return res.data;\n }, [request]);\n\n const deleteEndpoint = useCallback(async (endpointId: string) => {\n await request(`/endpoints/${endpointId}`, { method: 'DELETE' });\n }, [request]);\n\n const rotateSecret = useCallback(async (endpointId: string) => {\n const res = await request<PortalApiResponse<{ secret: string }>>(\n `/endpoints/${endpointId}/rotate-secret`,\n { method: 'POST' }\n );\n return res.data.secret;\n }, [request]);\n\n const listDeliveries = useCallback(async (endpointId: string, params?: {\n limit?: number;\n offset?: number;\n status?: string;\n }) => {\n const query = new URLSearchParams();\n if (params?.limit) query.set('limit', String(params.limit));\n if (params?.offset) query.set('offset', String(params.offset));\n if (params?.status) query.set('status', params.status);\n const qs = query.toString();\n\n const res = await request<PortalApiResponse<PortalDelivery[]>>(\n `/endpoints/${endpointId}/deliveries${qs ? `?${qs}` : ''}`\n );\n return { deliveries: res.data, total: res.meta.total || 0 };\n }, [request]);\n\n const getDelivery = useCallback(async (endpointId: string, deliveryId: string) => {\n const res = await request<PortalApiResponse<PortalDeliveryDetail>>(\n `/endpoints/${endpointId}/deliveries/${deliveryId}`\n );\n return res.data;\n }, [request]);\n\n const retryDelivery = useCallback(async (endpointId: string, deliveryId: string) => {\n await request(`/endpoints/${endpointId}/deliveries/${deliveryId}/retry`, {\n method: 'POST',\n });\n }, [request]);\n\n return {\n listEventTypes,\n listEndpoints,\n createEndpoint,\n updateEndpoint,\n deleteEndpoint,\n rotateSecret,\n listDeliveries,\n getDelivery,\n retryDelivery,\n };\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { PortalEndpoint, PortalEventType } from '../types';\nimport type { usePortalApi } from '../hooks/usePortalApi';\n\ninterface EndpointListProps {\n api: ReturnType<typeof usePortalApi>;\n eventTypes: PortalEventType[];\n onSelect: (endpoint: PortalEndpoint) => void;\n onCreated?: (endpoint: PortalEndpoint) => void;\n onDeleted?: (endpoint: PortalEndpoint) => void;\n onUpdated?: (endpoint: PortalEndpoint) => void;\n onError?: (error: Error) => void;\n}\n\nexport function EndpointList({\n api,\n eventTypes,\n onSelect,\n onCreated,\n onDeleted,\n onUpdated,\n onError,\n}: EndpointListProps) {\n const [endpoints, setEndpoints] = useState<PortalEndpoint[]>([]);\n const [isLoading, setIsLoading] = useState(true);\n const [showCreate, setShowCreate] = useState(false);\n const [newUrl, setNewUrl] = useState('');\n const [newEvents, setNewEvents] = useState<string[]>([]);\n const [newDesc, setNewDesc] = useState('');\n const [isCreating, setIsCreating] = useState(false);\n const [createdSecret, setCreatedSecret] = useState<string | null>(null);\n\n const fetchEndpoints = useCallback(async () => {\n try {\n setIsLoading(true);\n const result = await api.listEndpoints(100, 0);\n setEndpoints(result.endpoints);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to load endpoints'));\n } finally {\n setIsLoading(false);\n }\n }, [api, onError]);\n\n useEffect(() => { fetchEndpoints(); }, [fetchEndpoints]);\n\n const handleCreate = async () => {\n if (!newUrl || newEvents.length === 0) return;\n setIsCreating(true);\n try {\n const endpoint = await api.createEndpoint({\n url: newUrl,\n events: newEvents,\n description: newDesc || undefined,\n });\n setCreatedSecret(endpoint.secret);\n setNewUrl('');\n setNewEvents([]);\n setNewDesc('');\n await fetchEndpoints();\n onCreated?.(endpoint);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to create endpoint'));\n } finally {\n setIsCreating(false);\n }\n };\n\n const handleDelete = async (ep: PortalEndpoint) => {\n try {\n await api.deleteEndpoint(ep.id);\n await fetchEndpoints();\n onDeleted?.(ep);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to delete endpoint'));\n }\n };\n\n const handleToggleStatus = async (ep: PortalEndpoint) => {\n const newStatus = ep.status === 'active' ? 'paused' : 'active';\n try {\n const updated = await api.updateEndpoint(ep.id, { status: newStatus });\n await fetchEndpoints();\n onUpdated?.(updated);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to update endpoint'));\n }\n };\n\n const toggleEvent = (eventType: string) => {\n setNewEvents(prev =>\n prev.includes(eventType) ? prev.filter(e => e !== eventType) : [...prev, eventType]\n );\n };\n\n const statusBadgeClass = (status: string) => {\n switch (status) {\n case 'active': return 'zwp-badge zwp-badge--green';\n case 'paused': return 'zwp-badge zwp-badge--yellow';\n case 'disabled': return 'zwp-badge zwp-badge--red';\n default: return 'zwp-badge';\n }\n };\n\n if (isLoading) {\n return <div className=\"zwp-loading\">Loading endpoints...</div>;\n }\n\n return (\n <div className=\"zwp-endpoint-list\">\n <div className=\"zwp-section-header\">\n <h3 className=\"zwp-heading\">Endpoints</h3>\n <button\n className=\"zwp-btn zwp-btn--primary\"\n onClick={() => { setShowCreate(!showCreate); setCreatedSecret(null); }}\n >\n {showCreate ? 'Cancel' : 'Add Endpoint'}\n </button>\n </div>\n\n {createdSecret && (\n <div className=\"zwp-alert zwp-alert--warning\">\n <strong>Signing Secret</strong>\n <p>Store this secret securely. It will not be shown again.</p>\n <code className=\"zwp-secret\">{createdSecret}</code>\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => { navigator.clipboard.writeText(createdSecret); }}\n >\n Copy\n </button>\n </div>\n )}\n\n {showCreate && (\n <div className=\"zwp-create-form\">\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">URL</label>\n <input\n className=\"zwp-input\"\n type=\"url\"\n placeholder=\"https://your-app.com/webhooks\"\n value={newUrl}\n onChange={e => setNewUrl(e.target.value)}\n />\n </div>\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">Description (optional)</label>\n <input\n className=\"zwp-input\"\n type=\"text\"\n placeholder=\"Production endpoint\"\n value={newDesc}\n onChange={e => setNewDesc(e.target.value)}\n />\n </div>\n <div className=\"zwp-field\">\n <label className=\"zwp-label\">Events</label>\n <div className=\"zwp-event-picker\">\n {eventTypes.map(et => (\n <label key={et.event_type} className=\"zwp-checkbox-label\">\n <input\n type=\"checkbox\"\n checked={newEvents.includes(et.event_type)}\n onChange={() => toggleEvent(et.event_type)}\n />\n <span className=\"zwp-event-name\">{et.name}</span>\n <span className=\"zwp-event-type\">{et.event_type}</span>\n </label>\n ))}\n </div>\n </div>\n <button\n className=\"zwp-btn zwp-btn--primary\"\n onClick={handleCreate}\n disabled={isCreating || !newUrl || newEvents.length === 0}\n >\n {isCreating ? 'Creating...' : 'Create Endpoint'}\n </button>\n </div>\n )}\n\n {endpoints.length === 0 ? (\n <div className=\"zwp-empty\">\n <p>No endpoints configured yet.</p>\n <p>Add an endpoint to start receiving webhook deliveries.</p>\n </div>\n ) : (\n <div className=\"zwp-list\">\n {endpoints.map(ep => (\n <div key={ep.id} className=\"zwp-endpoint-card\" onClick={() => onSelect(ep)}>\n <div className=\"zwp-endpoint-header\">\n <code className=\"zwp-endpoint-url\">{ep.url}</code>\n <span className={statusBadgeClass(ep.status)}>{ep.status}</span>\n </div>\n {ep.description && (\n <p className=\"zwp-endpoint-desc\">{ep.description}</p>\n )}\n <div className=\"zwp-endpoint-meta\">\n <span>{ep.events.length} event{ep.events.length !== 1 ? 's' : ''}</span>\n <span>Created {new Date(ep.created_at).toLocaleDateString()}</span>\n </div>\n <div className=\"zwp-endpoint-actions\" onClick={e => e.stopPropagation()}>\n <button\n className=\"zwp-btn zwp-btn--sm zwp-btn--ghost\"\n onClick={() => handleToggleStatus(ep)}\n >\n {ep.status === 'active' ? 'Pause' : 'Resume'}\n </button>\n <button\n className=\"zwp-btn zwp-btn--sm zwp-btn--danger\"\n onClick={() => handleDelete(ep)}\n >\n Delete\n </button>\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n );\n}\n","import { useState, useEffect, useCallback } from 'react';\nimport type { PortalEndpoint, PortalDelivery } from '../types';\nimport type { usePortalApi } from '../hooks/usePortalApi';\n\ninterface EndpointDetailProps {\n api: ReturnType<typeof usePortalApi>;\n endpoint: PortalEndpoint;\n onBack: () => void;\n onRetried?: (deliveryId: string) => void;\n onError?: (error: Error) => void;\n}\n\nexport function EndpointDetail({ api, endpoint, onBack, onRetried, onError }: EndpointDetailProps) {\n const [deliveries, setDeliveries] = useState<PortalDelivery[]>([]);\n const [total, setTotal] = useState(0);\n const [isLoading, setIsLoading] = useState(true);\n const [statusFilter, setStatusFilter] = useState('');\n const [page, setPage] = useState(0);\n const [retrying, setRetrying] = useState<string | null>(null);\n const PAGE_SIZE = 20;\n\n const fetchDeliveries = useCallback(async () => {\n try {\n setIsLoading(true);\n const result = await api.listDeliveries(endpoint.id, {\n limit: PAGE_SIZE,\n offset: page * PAGE_SIZE,\n status: statusFilter || undefined,\n });\n setDeliveries(result.deliveries);\n setTotal(result.total);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to load deliveries'));\n } finally {\n setIsLoading(false);\n }\n }, [api, endpoint.id, page, statusFilter, onError]);\n\n useEffect(() => { fetchDeliveries(); }, [fetchDeliveries]);\n\n const handleRetry = async (deliveryId: string) => {\n setRetrying(deliveryId);\n try {\n await api.retryDelivery(endpoint.id, deliveryId);\n await fetchDeliveries();\n onRetried?.(deliveryId);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to retry delivery'));\n } finally {\n setRetrying(null);\n }\n };\n\n const handleRotateSecret = async () => {\n try {\n const secret = await api.rotateSecret(endpoint.id);\n alert(`New secret: ${secret}\\n\\nStore this securely. It will not be shown again.`);\n } catch (err) {\n onError?.(err instanceof Error ? err : new Error('Failed to rotate secret'));\n }\n };\n\n const statusBadgeClass = (status: string) => {\n switch (status) {\n case 'delivered': return 'zwp-badge zwp-badge--green';\n case 'failed': case 'exhausted': return 'zwp-badge zwp-badge--red';\n case 'retrying': case 'pending': return 'zwp-badge zwp-badge--yellow';\n default: return 'zwp-badge';\n }\n };\n\n const canRetry = (status: string) => status === 'failed' || status === 'exhausted';\n const totalPages = Math.ceil(total / PAGE_SIZE);\n\n return (\n <div className=\"zwp-endpoint-detail\">\n <button className=\"zwp-btn zwp-btn--ghost zwp-back-btn\" onClick={onBack}>\n &larr; Back to endpoints\n </button>\n\n <div className=\"zwp-detail-header\">\n <div>\n <code className=\"zwp-endpoint-url\">{endpoint.url}</code>\n <div className=\"zwp-endpoint-meta\">\n <span>{endpoint.events.length} event{endpoint.events.length !== 1 ? 's' : ''}</span>\n <span>Status: {endpoint.status}</span>\n </div>\n </div>\n <button className=\"zwp-btn zwp-btn--sm\" onClick={handleRotateSecret}>\n Rotate Secret\n </button>\n </div>\n\n <div className=\"zwp-events-list\">\n <h4 className=\"zwp-subheading\">Subscribed Events</h4>\n <div className=\"zwp-tags\">\n {endpoint.events.map(e => (\n <span key={e} className=\"zwp-tag\">{e}</span>\n ))}\n </div>\n </div>\n\n <div className=\"zwp-deliveries\">\n <div className=\"zwp-section-header\">\n <h4 className=\"zwp-subheading\">Delivery Log</h4>\n <select\n className=\"zwp-select\"\n value={statusFilter}\n onChange={e => { setStatusFilter(e.target.value); setPage(0); }}\n >\n <option value=\"\">All statuses</option>\n <option value=\"delivered\">Delivered</option>\n <option value=\"failed\">Failed</option>\n <option value=\"exhausted\">Exhausted</option>\n <option value=\"retrying\">Retrying</option>\n <option value=\"pending\">Pending</option>\n </select>\n </div>\n\n {isLoading ? (\n <div className=\"zwp-loading\">Loading deliveries...</div>\n ) : deliveries.length === 0 ? (\n <div className=\"zwp-empty\">\n <p>No deliveries yet.</p>\n </div>\n ) : (\n <>\n <table className=\"zwp-table\">\n <thead>\n <tr>\n <th>Event</th>\n <th>Status</th>\n <th>Attempts</th>\n <th>Response</th>\n <th>Time</th>\n <th></th>\n </tr>\n </thead>\n <tbody>\n {deliveries.map(d => (\n <tr key={d.id}>\n <td><code className=\"zwp-event-code\">{d.event_type}</code></td>\n <td><span className={statusBadgeClass(d.status)}>{d.status}</span></td>\n <td>{d.attempts}/{d.max_attempts}</td>\n <td>{d.last_response_status || '—'}</td>\n <td className=\"zwp-time\">\n {d.last_attempted_at\n ? new Date(d.last_attempted_at).toLocaleString()\n : new Date(d.created_at).toLocaleString()}\n </td>\n <td>\n {canRetry(d.status) && (\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => handleRetry(d.id)}\n disabled={retrying === d.id}\n >\n {retrying === d.id ? '...' : 'Retry'}\n </button>\n )}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n\n {totalPages > 1 && (\n <div className=\"zwp-pagination\">\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => setPage(p => p - 1)}\n disabled={page === 0}\n >\n Previous\n </button>\n <span className=\"zwp-page-info\">\n Page {page + 1} of {totalPages}\n </span>\n <button\n className=\"zwp-btn zwp-btn--sm\"\n onClick={() => setPage(p => p + 1)}\n disabled={page >= totalPages - 1}\n >\n Next\n </button>\n </div>\n )}\n </>\n )}\n </div>\n </div>\n );\n}\n","import { useState, useEffect } from 'react';\nimport type { WebhookPortalProps, PortalEndpoint, PortalEventType } from '../types';\nimport { usePortalApi } from '../hooks/usePortalApi';\nimport { EndpointList } from './EndpointList';\nimport { EndpointDetail } from './EndpointDetail';\n\nconst PREVIEW_ENDPOINTS: PortalEndpoint[] = [\n {\n id: 'preview-1',\n url: 'https://api.example.com/webhooks',\n description: 'Production endpoint',\n events: ['order.created', 'order.updated', 'payment.completed'],\n status: 'active',\n consecutive_failures: 0,\n created_at: new Date().toISOString(),\n updated_at: new Date().toISOString(),\n },\n {\n id: 'preview-2',\n url: 'https://staging.example.com/hooks',\n events: ['order.created'],\n status: 'paused',\n consecutive_failures: 0,\n created_at: new Date(Date.now() - 86400000).toISOString(),\n updated_at: new Date(Date.now() - 86400000).toISOString(),\n },\n];\n\nfunction PreviewEndpointList() {\n return (\n <div className=\"zwp-endpoint-list\">\n <div className=\"zwp-section-header\">\n <h3 className=\"zwp-heading\">Endpoints</h3>\n <button className=\"zwp-btn zwp-btn--primary\" disabled>Add Endpoint</button>\n </div>\n <div className=\"zwp-list\">\n {PREVIEW_ENDPOINTS.map(ep => (\n <div key={ep.id} className=\"zwp-endpoint-card\" style={{ cursor: 'default' }}>\n <div className=\"zwp-endpoint-header\">\n <code className=\"zwp-endpoint-url\">{ep.url}</code>\n <span className={`zwp-badge ${ep.status === 'active' ? 'zwp-badge--green' : 'zwp-badge--yellow'}`}>\n {ep.status}\n </span>\n </div>\n {ep.description && <p className=\"zwp-endpoint-desc\">{ep.description}</p>}\n <div className=\"zwp-endpoint-meta\">\n <span>{ep.events.length} event{ep.events.length !== 1 ? 's' : ''}</span>\n <span>Created {new Date(ep.created_at).toLocaleDateString()}</span>\n </div>\n </div>\n ))}\n </div>\n </div>\n );\n}\n\nexport function WebhookPortal({\n token,\n baseUrl,\n theme,\n preview,\n onEndpointCreated,\n onEndpointDeleted,\n onEndpointUpdated,\n onDeliveryRetried,\n onError,\n className,\n}: WebhookPortalProps) {\n const api = usePortalApi({ token, baseUrl });\n const [eventTypes, setEventTypes] = useState<PortalEventType[]>([]);\n const [selectedEndpoint, setSelectedEndpoint] = useState<PortalEndpoint | null>(null);\n const [error, setError] = useState<string | null>(null);\n\n useEffect(() => {\n if (preview) return;\n api.listEventTypes()\n .then(setEventTypes)\n .catch(err => {\n const e = err instanceof Error ? err : new Error('Failed to load event types');\n setError(e.message);\n onError?.(e);\n });\n }, [api, onError, preview]);\n\n const handleError = (err: Error) => {\n setError(err.message);\n onError?.(err);\n setTimeout(() => setError(null), 5000);\n };\n\n const style: Record<string, string> = {};\n if (theme?.accent) {\n style['--zwp-accent'] = theme.accent;\n }\n if (theme?.borderRadius !== undefined) {\n style['--zwp-radius'] = `${theme.borderRadius}px`;\n }\n\n const themeClass = theme?.mode === 'dark' ? 'zwp-dark' : 'zwp-light';\n\n return (\n <div\n className={`zwp-portal ${themeClass} ${className || ''}`}\n style={style}\n >\n {error && (\n <div className=\"zwp-alert zwp-alert--error\">\n {error}\n <button className=\"zwp-alert-close\" onClick={() => setError(null)}>&times;</button>\n </div>\n )}\n\n {preview ? (\n <PreviewEndpointList />\n ) : selectedEndpoint ? (\n <EndpointDetail\n api={api}\n endpoint={selectedEndpoint}\n onBack={() => setSelectedEndpoint(null)}\n onRetried={onDeliveryRetried}\n onError={handleError}\n />\n ) : (\n <EndpointList\n api={api}\n eventTypes={eventTypes}\n onSelect={setSelectedEndpoint}\n onCreated={onEndpointCreated}\n onDeleted={onEndpointDeleted}\n onUpdated={onEndpointUpdated}\n onError={handleError}\n />\n )}\n </div>\n );\n}\n"],"names":["_jsx","_jsxs","_Fragment"],"mappings":"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"}
@@ -0,0 +1 @@
1
+ .zwp-portal{--zwp-accent:#6366f1;--zwp-radius:8px;--zwp-font:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;--zwp-mono:"SF Mono",SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;box-sizing:border-box;font-family:var(--zwp-font);font-size:14px;line-height:1.5}.zwp-portal *,.zwp-portal :after,.zwp-portal :before{box-sizing:inherit}.zwp-light{--zwp-bg:#fff;--zwp-bg-secondary:#f8f9fa;--zwp-border:#e9ecef;--zwp-text:#212529;--zwp-text-secondary:#6c757d;--zwp-input-bg:#fff;--zwp-hover:#f1f3f5}.zwp-dark{--zwp-bg:#1a1b1e;--zwp-bg-secondary:#25262b;--zwp-border:#373a40;--zwp-text:#c1c2c5;--zwp-text-secondary:#909296;--zwp-input-bg:#25262b;--zwp-hover:#2c2e33}.zwp-portal{background:var(--zwp-bg);border:1px solid var(--zwp-border);border-radius:var(--zwp-radius);color:var(--zwp-text);padding:16px}.zwp-heading{font-size:16px;font-weight:600;margin:0}.zwp-subheading{font-size:14px;font-weight:600;margin:0 0 8px}.zwp-section-header{align-items:center;display:flex;justify-content:space-between;margin-bottom:12px}.zwp-btn{align-items:center;background:var(--zwp-bg-secondary);border:1px solid var(--zwp-border);border-radius:calc(var(--zwp-radius) - 2px);color:var(--zwp-text);cursor:pointer;display:inline-flex;font-family:var(--zwp-font);font-size:13px;gap:6px;padding:8px 16px;transition:background .15s}.zwp-btn:hover{background:var(--zwp-hover)}.zwp-btn:disabled{cursor:not-allowed;opacity:.5}.zwp-btn--primary{background:var(--zwp-accent);border-color:var(--zwp-accent);color:#fff}.zwp-btn--primary:hover{background:var(--zwp-accent);opacity:.9}.zwp-btn--danger{border-color:#e0313133;color:#e03131}.zwp-btn--danger:hover{background:#e0313112}.zwp-btn--ghost{background:transparent;border-color:transparent}.zwp-btn--ghost:hover{background:var(--zwp-hover)}.zwp-btn--sm{font-size:12px;padding:4px 10px}.zwp-input,.zwp-select{background:var(--zwp-input-bg);border:1px solid var(--zwp-border);border-radius:calc(var(--zwp-radius) - 2px);color:var(--zwp-text);font-family:var(--zwp-font);font-size:13px;padding:8px 12px;width:100%}.zwp-input:focus,.zwp-select:focus{border-color:var(--zwp-accent);box-shadow:0 0 0 2px color-mix(in srgb,var(--zwp-accent) 20%,transparent);outline:none}.zwp-select{cursor:pointer}.zwp-field{margin-bottom:12px}.zwp-label{display:block;font-size:13px;font-weight:500;margin-bottom:4px}.zwp-badge{border-radius:9999px;display:inline-block;font-size:11px;font-weight:600;letter-spacing:.02em;padding:2px 8px;text-transform:uppercase}.zwp-badge--green{background:#12b886;color:#fff}.zwp-badge--yellow{background:#fab005;color:#000}.zwp-badge--red{background:#e03131;color:#fff}.zwp-tags{display:flex;flex-wrap:wrap;gap:4px}.zwp-tag{background:var(--zwp-bg-secondary);border:1px solid var(--zwp-border);border-radius:calc(var(--zwp-radius) - 2px);display:inline-block;font-family:var(--zwp-mono);font-size:12px;padding:2px 8px}.zwp-alert{border-radius:var(--zwp-radius);margin-bottom:12px;padding:12px 16px;position:relative}.zwp-alert--error{background:#e0313112;border:1px solid #e0313133;color:#e03131}.zwp-alert--warning{background:#fab00512;border:1px solid #fab00533;color:var(--zwp-text)}.zwp-alert-close{background:none;border:none;color:inherit;cursor:pointer;font-size:16px;position:absolute;right:12px;top:8px}.zwp-secret{background:var(--zwp-bg-secondary);border:1px solid var(--zwp-border);border-radius:calc(var(--zwp-radius) - 2px);display:block;font-family:var(--zwp-mono);font-size:13px;margin:8px 0;padding:8px;word-break:break-all}.zwp-endpoint-card{border:1px solid var(--zwp-border);border-radius:var(--zwp-radius);cursor:pointer;margin-bottom:8px;padding:12px 16px;transition:background .15s}.zwp-endpoint-card:hover{background:var(--zwp-hover)}.zwp-endpoint-header{align-items:center;display:flex;gap:8px;justify-content:space-between}.zwp-endpoint-url{font-family:var(--zwp-mono);font-size:13px;font-weight:500}.zwp-endpoint-desc{margin:4px 0 0}.zwp-endpoint-desc,.zwp-endpoint-meta{color:var(--zwp-text-secondary);font-size:12px}.zwp-endpoint-meta{display:flex;gap:16px;margin-top:8px}.zwp-endpoint-actions{display:flex;gap:8px;margin-top:8px}.zwp-create-form{background:var(--zwp-bg-secondary);border:1px solid var(--zwp-border);border-radius:var(--zwp-radius);margin-bottom:12px;padding:16px}.zwp-event-picker{background:var(--zwp-input-bg);border:1px solid var(--zwp-border);border-radius:calc(var(--zwp-radius) - 2px);display:flex;flex-direction:column;gap:6px;max-height:200px;overflow-y:auto;padding:8px}.zwp-checkbox-label{align-items:center;cursor:pointer;display:flex;font-size:13px;gap:8px}.zwp-event-name{font-weight:500}.zwp-event-type{color:var(--zwp-text-secondary);font-family:var(--zwp-mono);font-size:11px}.zwp-table{border-collapse:collapse;font-size:13px;width:100%}.zwp-table th{border-bottom:2px solid var(--zwp-border);color:var(--zwp-text-secondary);font-size:12px;font-weight:600;letter-spacing:.03em;padding:8px 12px;text-align:left;text-transform:uppercase}.zwp-table td{border-bottom:1px solid var(--zwp-border);padding:8px 12px}.zwp-table tr:hover td{background:var(--zwp-hover)}.zwp-event-code{font-family:var(--zwp-mono);font-size:12px}.zwp-time{color:var(--zwp-text-secondary);font-size:12px;white-space:nowrap}.zwp-pagination{align-items:center;display:flex;gap:12px;justify-content:center;margin-top:12px}.zwp-page-info{color:var(--zwp-text-secondary);font-size:13px}.zwp-back-btn{margin-bottom:12px}.zwp-detail-header{align-items:flex-start;display:flex;justify-content:space-between;margin-bottom:16px}.zwp-events-list{margin-bottom:16px}.zwp-empty,.zwp-loading{color:var(--zwp-text-secondary);padding:24px;text-align:center}
package/package.json ADDED
@@ -0,0 +1,76 @@
1
+ {
2
+ "name": "@zyphr-dev/webhook-portal",
3
+ "version": "0.1.0",
4
+ "description": "Embeddable webhook management portal for Zyphr WaaS",
5
+ "type": "module",
6
+ "main": "./dist/index.cjs",
7
+ "module": "./dist/index.js",
8
+ "types": "./dist/index.d.ts",
9
+ "exports": {
10
+ ".": {
11
+ "types": "./dist/index.d.ts",
12
+ "import": "./dist/index.js",
13
+ "require": "./dist/index.cjs"
14
+ },
15
+ "./styles.css": "./dist/styles.css"
16
+ },
17
+ "sideEffects": [
18
+ "*.css"
19
+ ],
20
+ "publishConfig": {
21
+ "access": "public"
22
+ },
23
+ "files": [
24
+ "dist",
25
+ "README.md"
26
+ ],
27
+ "scripts": {
28
+ "build": "rollup -c",
29
+ "dev": "rollup -c -w",
30
+ "typecheck": "tsc --noEmit",
31
+ "lint": "eslint src --ext .ts,.tsx",
32
+ "test": "vitest run",
33
+ "clean": "rm -rf dist",
34
+ "prepublishOnly": "yarn clean && yarn build"
35
+ },
36
+ "peerDependencies": {
37
+ "react": ">=17.0.0",
38
+ "react-dom": ">=17.0.0"
39
+ },
40
+ "devDependencies": {
41
+ "@rollup/plugin-commonjs": "^25.0.0",
42
+ "@rollup/plugin-node-resolve": "^15.0.0",
43
+ "@rollup/plugin-typescript": "^11.0.0",
44
+ "@types/react": "^19.0.0",
45
+ "@types/react-dom": "^19.0.0",
46
+ "@typescript-eslint/eslint-plugin": "^7.0.0",
47
+ "@typescript-eslint/parser": "^7.0.0",
48
+ "eslint": "^8.57.0",
49
+ "eslint-plugin-react": "^7.34.0",
50
+ "eslint-plugin-react-hooks": "^4.6.0",
51
+ "postcss": "^8.5.6",
52
+ "react": "^19.2.4",
53
+ "react-dom": "^19.2.4",
54
+ "rollup": "^4.0.0",
55
+ "rollup-plugin-dts": "^6.0.0",
56
+ "rollup-plugin-postcss": "^4.0.0",
57
+ "tslib": "^2.6.0",
58
+ "typescript": "^5.3.0",
59
+ "vitest": "^4.0.18"
60
+ },
61
+ "keywords": [
62
+ "zyphr",
63
+ "webhooks",
64
+ "portal",
65
+ "react",
66
+ "embeddable",
67
+ "waas"
68
+ ],
69
+ "license": "MIT",
70
+ "homepage": "https://zyphr.dev/docs/guides/waas-embedded-portal",
71
+ "repository": {
72
+ "type": "git",
73
+ "url": "https://github.com/arcraz/zyphr.git",
74
+ "directory": "packages/webhook-portal"
75
+ }
76
+ }