@checkflow/sdk 1.1.0 → 1.1.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +63 -219
- package/dist/chunk-CD33QAA6.mjs +131 -0
- package/dist/chunk-CQ56DMFR.mjs +83 -0
- package/dist/highlighter-D_wZWHlS.d.mts +71 -0
- package/dist/highlighter-D_wZWHlS.d.ts +71 -0
- package/dist/highlighter-W4XDALRE.mjs +8 -0
- package/dist/index.d.mts +41 -0
- package/dist/index.d.ts +38 -20
- package/dist/index.js +607 -17221
- package/dist/index.mjs +411 -0
- package/dist/react.d.mts +28 -0
- package/dist/react.d.ts +28 -0
- package/dist/react.js +743 -0
- package/dist/react.mjs +51 -0
- package/dist/screenshot-CUMBPE2T.mjs +12 -0
- package/dist/vue.d.mts +26 -0
- package/dist/vue.d.ts +26 -0
- package/dist/vue.js +744 -0
- package/dist/vue.mjs +53 -0
- package/package.json +38 -51
- package/dist/analytics-tracker.d.ts +0 -112
- package/dist/annotation/editor.d.ts +0 -72
- package/dist/annotation/index.d.ts +0 -9
- package/dist/annotation/styles.d.ts +0 -6
- package/dist/annotation/toolbar.d.ts +0 -32
- package/dist/annotation/types.d.ts +0 -85
- package/dist/api-client.d.ts +0 -76
- package/dist/checkflow.css +0 -1
- package/dist/checkflow.d.ts +0 -112
- package/dist/context-capture.d.ts +0 -42
- package/dist/error-capture.d.ts +0 -60
- package/dist/index.esm.js +0 -17210
- package/dist/index.esm.js.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/privacy/detector.d.ts +0 -56
- package/dist/privacy/index.d.ts +0 -8
- package/dist/privacy/masker.d.ts +0 -43
- package/dist/privacy/types.d.ts +0 -54
- package/dist/react/index.d.ts +0 -77
- package/dist/session-recording-rrweb.d.ts +0 -100
- package/dist/session-recording.d.ts +0 -74
- package/dist/types.d.ts +0 -299
- package/dist/vue/index.d.ts +0 -55
- package/dist/widget/Widget.d.ts +0 -98
- package/dist/widget/index.d.ts +0 -2
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,411 @@
|
|
|
1
|
+
import {
|
|
2
|
+
captureScreenshot,
|
|
3
|
+
clearScreenshot,
|
|
4
|
+
loadHtml2Canvas
|
|
5
|
+
} from "./chunk-CQ56DMFR.mjs";
|
|
6
|
+
import {
|
|
7
|
+
startHighlighting
|
|
8
|
+
} from "./chunk-CD33QAA6.mjs";
|
|
9
|
+
|
|
10
|
+
// src/collector.ts
|
|
11
|
+
function collectContext() {
|
|
12
|
+
const ua = navigator.userAgent;
|
|
13
|
+
return {
|
|
14
|
+
url: window.location.href,
|
|
15
|
+
viewport: {
|
|
16
|
+
width: window.innerWidth,
|
|
17
|
+
height: window.innerHeight,
|
|
18
|
+
device: window.innerWidth < 768 ? "mobile" : window.innerWidth < 1024 ? "tablet" : "desktop"
|
|
19
|
+
},
|
|
20
|
+
user_agent: ua,
|
|
21
|
+
browser: detectBrowser(ua),
|
|
22
|
+
os: detectOS(ua),
|
|
23
|
+
locale: navigator.language,
|
|
24
|
+
timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
function collectPerformance() {
|
|
28
|
+
try {
|
|
29
|
+
const entries = performance.getEntriesByType("paint");
|
|
30
|
+
const metrics = {};
|
|
31
|
+
entries.forEach((e) => {
|
|
32
|
+
if (e.name === "first-contentful-paint") metrics.fcp = Math.round(e.startTime);
|
|
33
|
+
});
|
|
34
|
+
const nav = performance.getEntriesByType("navigation")[0];
|
|
35
|
+
if (nav) {
|
|
36
|
+
metrics.dom_load = Math.round(nav.domContentLoadedEventEnd - nav.startTime);
|
|
37
|
+
metrics.load = Math.round(nav.loadEventEnd - nav.startTime);
|
|
38
|
+
}
|
|
39
|
+
return Object.keys(metrics).length > 0 ? metrics : void 0;
|
|
40
|
+
} catch {
|
|
41
|
+
return void 0;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
function detectBrowser(ua) {
|
|
45
|
+
if (ua.includes("Firefox/")) return "Firefox";
|
|
46
|
+
if (ua.includes("Edg/")) return "Edge";
|
|
47
|
+
if (ua.includes("Chrome/")) return "Chrome";
|
|
48
|
+
if (ua.includes("Safari/")) return "Safari";
|
|
49
|
+
return "Unknown";
|
|
50
|
+
}
|
|
51
|
+
function detectOS(ua) {
|
|
52
|
+
if (ua.includes("Windows")) return "Windows";
|
|
53
|
+
if (ua.includes("Mac OS")) return "macOS";
|
|
54
|
+
if (ua.includes("Linux")) return "Linux";
|
|
55
|
+
if (ua.includes("Android")) return "Android";
|
|
56
|
+
if (ua.includes("iPhone") || ua.includes("iPad")) return "iOS";
|
|
57
|
+
return "Unknown";
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// src/console-interceptor.ts
|
|
61
|
+
var MAX_LOGS = 50;
|
|
62
|
+
var logs = [];
|
|
63
|
+
var errorsCapture = [];
|
|
64
|
+
var installed = false;
|
|
65
|
+
function installInterceptors() {
|
|
66
|
+
if (installed) return;
|
|
67
|
+
installed = true;
|
|
68
|
+
const origConsole = {
|
|
69
|
+
log: console.log,
|
|
70
|
+
warn: console.warn,
|
|
71
|
+
error: console.error
|
|
72
|
+
};
|
|
73
|
+
["log", "warn", "error"].forEach((level) => {
|
|
74
|
+
console[level] = (...args) => {
|
|
75
|
+
logs.push({
|
|
76
|
+
level,
|
|
77
|
+
message: args.map((a) => typeof a === "string" ? a : JSON.stringify(a)).join(" "),
|
|
78
|
+
timestamp: Date.now()
|
|
79
|
+
});
|
|
80
|
+
if (logs.length > MAX_LOGS) logs.shift();
|
|
81
|
+
origConsole[level](...args);
|
|
82
|
+
};
|
|
83
|
+
});
|
|
84
|
+
window.addEventListener("error", (event) => {
|
|
85
|
+
errorsCapture.push({
|
|
86
|
+
message: event.message,
|
|
87
|
+
filename: event.filename,
|
|
88
|
+
lineno: event.lineno,
|
|
89
|
+
colno: event.colno,
|
|
90
|
+
timestamp: Date.now()
|
|
91
|
+
});
|
|
92
|
+
if (errorsCapture.length > MAX_LOGS) errorsCapture.shift();
|
|
93
|
+
});
|
|
94
|
+
window.addEventListener("unhandledrejection", (event) => {
|
|
95
|
+
errorsCapture.push({
|
|
96
|
+
message: String(event.reason),
|
|
97
|
+
type: "unhandledrejection",
|
|
98
|
+
timestamp: Date.now()
|
|
99
|
+
});
|
|
100
|
+
if (errorsCapture.length > MAX_LOGS) errorsCapture.shift();
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function getConsoleLogs() {
|
|
104
|
+
return [...logs];
|
|
105
|
+
}
|
|
106
|
+
function getJavascriptErrors() {
|
|
107
|
+
return [...errorsCapture];
|
|
108
|
+
}
|
|
109
|
+
function clearLogs() {
|
|
110
|
+
logs = [];
|
|
111
|
+
errorsCapture = [];
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
// src/widget.ts
|
|
115
|
+
var DEFAULT_CONFIG = {
|
|
116
|
+
position: "bottom-right",
|
|
117
|
+
color: "#1e3a5f",
|
|
118
|
+
text: "Report Bug",
|
|
119
|
+
showOnInit: true
|
|
120
|
+
};
|
|
121
|
+
var container = null;
|
|
122
|
+
var onSubmitCallback = null;
|
|
123
|
+
var screenshotDataUrl = null;
|
|
124
|
+
var annotationsData = [];
|
|
125
|
+
function mountWidget(config2 = {}, onSubmit, opts) {
|
|
126
|
+
if (container) return;
|
|
127
|
+
onSubmitCallback = onSubmit;
|
|
128
|
+
const cfg = { ...DEFAULT_CONFIG, ...config2 };
|
|
129
|
+
container = document.createElement("div");
|
|
130
|
+
container.id = "checkflow-widget";
|
|
131
|
+
container.innerHTML = getWidgetHTML(cfg);
|
|
132
|
+
document.body.appendChild(container);
|
|
133
|
+
const btn = container.querySelector("#cf-trigger");
|
|
134
|
+
const form = container.querySelector("#cf-form");
|
|
135
|
+
const closeBtn = container.querySelector("#cf-close");
|
|
136
|
+
const submitBtn = container.querySelector("#cf-submit");
|
|
137
|
+
const screenshotBtn = container.querySelector("#cf-screenshot");
|
|
138
|
+
const highlightBtn = container.querySelector("#cf-highlight");
|
|
139
|
+
const screenshotPreview = container.querySelector("#cf-screenshot-preview");
|
|
140
|
+
btn?.addEventListener("click", () => {
|
|
141
|
+
form.style.display = form.style.display === "none" ? "flex" : "none";
|
|
142
|
+
screenshotDataUrl = null;
|
|
143
|
+
annotationsData = [];
|
|
144
|
+
if (screenshotPreview) screenshotPreview.style.display = "none";
|
|
145
|
+
});
|
|
146
|
+
closeBtn?.addEventListener("click", () => {
|
|
147
|
+
form.style.display = "none";
|
|
148
|
+
});
|
|
149
|
+
screenshotBtn?.addEventListener("click", async () => {
|
|
150
|
+
if (!opts?.onScreenshot) return;
|
|
151
|
+
screenshotBtn.textContent = "Capturing...";
|
|
152
|
+
form.style.display = "none";
|
|
153
|
+
try {
|
|
154
|
+
const data = await opts.onScreenshot();
|
|
155
|
+
if (data) {
|
|
156
|
+
screenshotDataUrl = data;
|
|
157
|
+
if (screenshotPreview) {
|
|
158
|
+
screenshotPreview.querySelector("img").src = data;
|
|
159
|
+
screenshotPreview.style.display = "block";
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
} catch {
|
|
163
|
+
}
|
|
164
|
+
form.style.display = "flex";
|
|
165
|
+
screenshotBtn.innerHTML = '<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg> Screenshot';
|
|
166
|
+
});
|
|
167
|
+
highlightBtn?.addEventListener("click", async () => {
|
|
168
|
+
if (!opts?.onHighlight) return;
|
|
169
|
+
form.style.display = "none";
|
|
170
|
+
try {
|
|
171
|
+
const annotations = await opts.onHighlight();
|
|
172
|
+
if (annotations && annotations.length > 0) {
|
|
173
|
+
annotationsData = annotations;
|
|
174
|
+
highlightBtn.innerHTML = `<svg width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg> ${annotations.length} highlighted`;
|
|
175
|
+
}
|
|
176
|
+
} catch {
|
|
177
|
+
}
|
|
178
|
+
form.style.display = "flex";
|
|
179
|
+
});
|
|
180
|
+
submitBtn?.addEventListener("click", () => {
|
|
181
|
+
const title = container.querySelector("#cf-title")?.value;
|
|
182
|
+
const desc = container.querySelector("#cf-desc")?.value;
|
|
183
|
+
const type = container.querySelector("#cf-type")?.value;
|
|
184
|
+
const priority = container.querySelector("#cf-priority")?.value;
|
|
185
|
+
if (!title?.trim()) return;
|
|
186
|
+
onSubmitCallback?.({ title, description: desc, type, priority, screenshot: screenshotDataUrl || void 0, annotations: annotationsData.length > 0 ? annotationsData : void 0 });
|
|
187
|
+
container.querySelector("#cf-title").value = "";
|
|
188
|
+
container.querySelector("#cf-desc").value = "";
|
|
189
|
+
screenshotDataUrl = null;
|
|
190
|
+
annotationsData = [];
|
|
191
|
+
if (screenshotPreview) screenshotPreview.style.display = "none";
|
|
192
|
+
form.style.display = "none";
|
|
193
|
+
showToast("Feedback sent!");
|
|
194
|
+
});
|
|
195
|
+
}
|
|
196
|
+
function unmountWidget() {
|
|
197
|
+
if (container) {
|
|
198
|
+
container.remove();
|
|
199
|
+
container = null;
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
function showToast(msg) {
|
|
203
|
+
const toast = document.createElement("div");
|
|
204
|
+
toast.textContent = msg;
|
|
205
|
+
toast.style.cssText = "position:fixed;bottom:80px;right:20px;background:#10b981;color:#fff;padding:8px 16px;border-radius:8px;font-size:13px;z-index:100001;font-family:system-ui;box-shadow:0 2px 8px rgba(0,0,0,.15);";
|
|
206
|
+
document.body.appendChild(toast);
|
|
207
|
+
setTimeout(() => toast.remove(), 3e3);
|
|
208
|
+
}
|
|
209
|
+
function getPositionCSS(pos) {
|
|
210
|
+
switch (pos) {
|
|
211
|
+
case "bottom-left":
|
|
212
|
+
return "bottom:20px;left:20px;";
|
|
213
|
+
case "top-right":
|
|
214
|
+
return "top:20px;right:20px;";
|
|
215
|
+
case "top-left":
|
|
216
|
+
return "top:20px;left:20px;";
|
|
217
|
+
default:
|
|
218
|
+
return "bottom:20px;right:20px;";
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
function getFormPositionCSS(pos) {
|
|
222
|
+
switch (pos) {
|
|
223
|
+
case "bottom-left":
|
|
224
|
+
return "bottom:70px;left:20px;";
|
|
225
|
+
case "top-right":
|
|
226
|
+
return "top:70px;right:20px;";
|
|
227
|
+
case "top-left":
|
|
228
|
+
return "top:70px;left:20px;";
|
|
229
|
+
default:
|
|
230
|
+
return "bottom:70px;right:20px;";
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
function getWidgetHTML(cfg) {
|
|
234
|
+
const posBtn = getPositionCSS(cfg.position);
|
|
235
|
+
const posForm = getFormPositionCSS(cfg.position);
|
|
236
|
+
return `
|
|
237
|
+
<style>
|
|
238
|
+
#cf-trigger{position:fixed;${posBtn}z-index:100000;background:${cfg.color};color:#fff;border:none;border-radius:50px;padding:10px 18px;font-size:13px;font-family:system-ui,-apple-system,sans-serif;cursor:pointer;box-shadow:0 4px 12px rgba(0,0,0,.15);display:flex;align-items:center;gap:6px;transition:transform .15s}
|
|
239
|
+
#cf-trigger:hover{transform:scale(1.05)}
|
|
240
|
+
#cf-trigger svg{width:16px;height:16px}
|
|
241
|
+
#cf-form{position:fixed;${posForm}z-index:100000;background:#fff;border-radius:12px;box-shadow:0 8px 30px rgba(0,0,0,.12);width:360px;padding:16px;font-family:system-ui,-apple-system,sans-serif;display:none;flex-direction:column;gap:10px}
|
|
242
|
+
#cf-form h3{margin:0;font-size:15px;font-weight:600;color:#111}
|
|
243
|
+
#cf-form input,#cf-form textarea,#cf-form select{width:100%;padding:8px 10px;border:1px solid #e2e8f0;border-radius:8px;font-size:13px;font-family:inherit;box-sizing:border-box;outline:none;transition:border .15s}
|
|
244
|
+
#cf-form input:focus,#cf-form textarea:focus,#cf-form select:focus{border-color:${cfg.color}}
|
|
245
|
+
#cf-form textarea{resize:vertical;min-height:60px}
|
|
246
|
+
.cf-row{display:flex;gap:8px}
|
|
247
|
+
.cf-row select{flex:1}
|
|
248
|
+
.cf-tools{display:flex;gap:6px}
|
|
249
|
+
.cf-tool-btn{display:flex;align-items:center;gap:4px;padding:6px 10px;border:1px solid #e2e8f0;border-radius:6px;background:#f8fafc;color:#475569;font-size:11px;cursor:pointer;font-family:inherit;transition:all .15s}
|
|
250
|
+
.cf-tool-btn:hover{background:#f1f5f9;border-color:#cbd5e1}
|
|
251
|
+
.cf-tool-btn svg{width:14px;height:14px}
|
|
252
|
+
#cf-submit{background:${cfg.color};color:#fff;border:none;border-radius:8px;padding:9px;font-size:13px;font-weight:500;cursor:pointer;transition:opacity .15s}
|
|
253
|
+
#cf-submit:hover{opacity:.9}
|
|
254
|
+
#cf-close{position:absolute;top:10px;right:12px;background:none;border:none;cursor:pointer;font-size:18px;color:#94a3b8;line-height:1}
|
|
255
|
+
#cf-screenshot-preview{display:none;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;max-height:120px}
|
|
256
|
+
#cf-screenshot-preview img{width:100%;height:auto;display:block}
|
|
257
|
+
</style>
|
|
258
|
+
<button id="cf-trigger">
|
|
259
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><circle cx="12" cy="12" r="10"/><line x1="12" y1="8" x2="12" y2="12"/><line x1="12" y1="16" x2="12.01" y2="16"/></svg>
|
|
260
|
+
${cfg.text}
|
|
261
|
+
</button>
|
|
262
|
+
<div id="cf-form">
|
|
263
|
+
<button id="cf-close">×</button>
|
|
264
|
+
<h3>Report Feedback</h3>
|
|
265
|
+
<input id="cf-title" type="text" placeholder="Title *" />
|
|
266
|
+
<textarea id="cf-desc" placeholder="Description (optional)"></textarea>
|
|
267
|
+
<div class="cf-row">
|
|
268
|
+
<select id="cf-type">
|
|
269
|
+
<option value="BUG">Bug</option>
|
|
270
|
+
<option value="FEATURE">Feature</option>
|
|
271
|
+
<option value="IMPROVEMENT">Improvement</option>
|
|
272
|
+
<option value="QUESTION">Question</option>
|
|
273
|
+
</select>
|
|
274
|
+
<select id="cf-priority">
|
|
275
|
+
<option value="LOW">Low</option>
|
|
276
|
+
<option value="MEDIUM" selected>Medium</option>
|
|
277
|
+
<option value="HIGH">High</option>
|
|
278
|
+
<option value="CRITICAL">Critical</option>
|
|
279
|
+
</select>
|
|
280
|
+
</div>
|
|
281
|
+
<div class="cf-tools">
|
|
282
|
+
<button type="button" class="cf-tool-btn" id="cf-screenshot">
|
|
283
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="3" y="3" width="18" height="18" rx="2"/><circle cx="8.5" cy="8.5" r="1.5"/><path d="m21 15-5-5L5 21"/></svg>
|
|
284
|
+
Screenshot
|
|
285
|
+
</button>
|
|
286
|
+
<button type="button" class="cf-tool-btn" id="cf-highlight">
|
|
287
|
+
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M12 20h9"/><path d="M16.5 3.5a2.121 2.121 0 0 1 3 3L7 19l-4 1 1-4L16.5 3.5z"/></svg>
|
|
288
|
+
Highlight
|
|
289
|
+
</button>
|
|
290
|
+
</div>
|
|
291
|
+
<div id="cf-screenshot-preview"><img src="" alt="screenshot" /></div>
|
|
292
|
+
<button id="cf-submit">Send Feedback</button>
|
|
293
|
+
</div>`;
|
|
294
|
+
}
|
|
295
|
+
|
|
296
|
+
// src/index.ts
|
|
297
|
+
var SDK_VERSION = "1.1.0";
|
|
298
|
+
var DEFAULT_ENDPOINT = "https://api.checkflow.space/api/v1";
|
|
299
|
+
var config = null;
|
|
300
|
+
function init(cfg) {
|
|
301
|
+
config = {
|
|
302
|
+
enabled: true,
|
|
303
|
+
endpoint: DEFAULT_ENDPOINT,
|
|
304
|
+
environment: "production",
|
|
305
|
+
...cfg
|
|
306
|
+
};
|
|
307
|
+
if (!config.enabled) return;
|
|
308
|
+
installInterceptors();
|
|
309
|
+
if (typeof window !== "undefined") {
|
|
310
|
+
loadHtml2Canvas().catch(() => {
|
|
311
|
+
});
|
|
312
|
+
}
|
|
313
|
+
if (typeof window !== "undefined" && config.widget?.showOnInit !== false) {
|
|
314
|
+
mountWidget(
|
|
315
|
+
config.widget,
|
|
316
|
+
(data) => {
|
|
317
|
+
sendFeedback({
|
|
318
|
+
title: data.title,
|
|
319
|
+
description: data.description,
|
|
320
|
+
type: data.type,
|
|
321
|
+
priority: data.priority,
|
|
322
|
+
screenshot_data: data.screenshot,
|
|
323
|
+
annotations: data.annotations
|
|
324
|
+
});
|
|
325
|
+
},
|
|
326
|
+
{
|
|
327
|
+
onScreenshot: () => captureScreenshot(),
|
|
328
|
+
onHighlight: () => startHighlighting()
|
|
329
|
+
}
|
|
330
|
+
);
|
|
331
|
+
}
|
|
332
|
+
}
|
|
333
|
+
async function sendFeedback(data) {
|
|
334
|
+
if (!config) {
|
|
335
|
+
return { success: false, error: { message: "SDK not initialized. Call init() first.", code: "NOT_INITIALIZED" } };
|
|
336
|
+
}
|
|
337
|
+
const context = typeof window !== "undefined" ? collectContext() : {};
|
|
338
|
+
const perf = typeof window !== "undefined" ? collectPerformance() : void 0;
|
|
339
|
+
const consoleLogs = getConsoleLogs();
|
|
340
|
+
const jsErrors = getJavascriptErrors();
|
|
341
|
+
const payload = {
|
|
342
|
+
...data,
|
|
343
|
+
...context,
|
|
344
|
+
environment: config.environment,
|
|
345
|
+
performance_metrics: perf,
|
|
346
|
+
console_logs: consoleLogs.length > 0 ? consoleLogs : void 0,
|
|
347
|
+
javascript_errors: jsErrors.length > 0 ? jsErrors : void 0,
|
|
348
|
+
sdk_version: SDK_VERSION
|
|
349
|
+
};
|
|
350
|
+
if (data.screenshot_data) {
|
|
351
|
+
payload.screenshot_data = data.screenshot_data;
|
|
352
|
+
}
|
|
353
|
+
if (data.annotations && data.annotations.length > 0) {
|
|
354
|
+
payload.annotations = data.annotations;
|
|
355
|
+
}
|
|
356
|
+
try {
|
|
357
|
+
const res = await fetch(`${config.endpoint}/sdk/feedback`, {
|
|
358
|
+
method: "POST",
|
|
359
|
+
headers: {
|
|
360
|
+
"Content-Type": "application/json",
|
|
361
|
+
"X-API-Key": config.apiKey
|
|
362
|
+
},
|
|
363
|
+
body: JSON.stringify(payload)
|
|
364
|
+
});
|
|
365
|
+
const json = await res.json();
|
|
366
|
+
if (!res.ok) {
|
|
367
|
+
return { success: false, error: json.error || { message: "Request failed", code: "REQUEST_FAILED" } };
|
|
368
|
+
}
|
|
369
|
+
return { success: true, data: json.data };
|
|
370
|
+
} catch (err) {
|
|
371
|
+
return { success: false, error: { message: err.message, code: "NETWORK_ERROR" } };
|
|
372
|
+
}
|
|
373
|
+
}
|
|
374
|
+
function showWidget() {
|
|
375
|
+
if (!config) return;
|
|
376
|
+
mountWidget(
|
|
377
|
+
config.widget,
|
|
378
|
+
(data) => {
|
|
379
|
+
sendFeedback({
|
|
380
|
+
title: data.title,
|
|
381
|
+
description: data.description,
|
|
382
|
+
type: data.type,
|
|
383
|
+
priority: data.priority,
|
|
384
|
+
screenshot_data: data.screenshot,
|
|
385
|
+
annotations: data.annotations
|
|
386
|
+
});
|
|
387
|
+
},
|
|
388
|
+
{
|
|
389
|
+
onScreenshot: () => captureScreenshot(),
|
|
390
|
+
onHighlight: () => startHighlighting()
|
|
391
|
+
}
|
|
392
|
+
);
|
|
393
|
+
}
|
|
394
|
+
function hideWidget() {
|
|
395
|
+
unmountWidget();
|
|
396
|
+
}
|
|
397
|
+
function destroy() {
|
|
398
|
+
unmountWidget();
|
|
399
|
+
clearLogs();
|
|
400
|
+
clearScreenshot();
|
|
401
|
+
config = null;
|
|
402
|
+
}
|
|
403
|
+
export {
|
|
404
|
+
captureScreenshot,
|
|
405
|
+
destroy,
|
|
406
|
+
hideWidget,
|
|
407
|
+
init,
|
|
408
|
+
sendFeedback,
|
|
409
|
+
showWidget,
|
|
410
|
+
startHighlighting
|
|
411
|
+
};
|
package/dist/react.d.mts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { a as FeedbackResponse, H as HighlightAnnotation, C as CheckflowConfig } from './highlighter-D_wZWHlS.mjs';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Initialize Checkflow in a React/Next.js app.
|
|
5
|
+
* Call this in your root layout or _app file.
|
|
6
|
+
*/
|
|
7
|
+
declare function useCheckflowInit(config: CheckflowConfig): void;
|
|
8
|
+
/**
|
|
9
|
+
* Hook to send feedback programmatically from React components.
|
|
10
|
+
*/
|
|
11
|
+
declare function useCheckflowFeedback(): {
|
|
12
|
+
send: (data: {
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
type?: string;
|
|
16
|
+
priority?: string;
|
|
17
|
+
}) => Promise<FeedbackResponse>;
|
|
18
|
+
screenshot: () => Promise<string | null>;
|
|
19
|
+
highlight: () => Promise<HighlightAnnotation[]>;
|
|
20
|
+
show: () => Promise<void>;
|
|
21
|
+
hide: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Cleanup function for React useEffect.
|
|
25
|
+
*/
|
|
26
|
+
declare function destroyCheckflow(): void;
|
|
27
|
+
|
|
28
|
+
export { destroyCheckflow, useCheckflowFeedback, useCheckflowInit };
|
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { a as FeedbackResponse, H as HighlightAnnotation, C as CheckflowConfig } from './highlighter-D_wZWHlS.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Initialize Checkflow in a React/Next.js app.
|
|
5
|
+
* Call this in your root layout or _app file.
|
|
6
|
+
*/
|
|
7
|
+
declare function useCheckflowInit(config: CheckflowConfig): void;
|
|
8
|
+
/**
|
|
9
|
+
* Hook to send feedback programmatically from React components.
|
|
10
|
+
*/
|
|
11
|
+
declare function useCheckflowFeedback(): {
|
|
12
|
+
send: (data: {
|
|
13
|
+
title: string;
|
|
14
|
+
description?: string;
|
|
15
|
+
type?: string;
|
|
16
|
+
priority?: string;
|
|
17
|
+
}) => Promise<FeedbackResponse>;
|
|
18
|
+
screenshot: () => Promise<string | null>;
|
|
19
|
+
highlight: () => Promise<HighlightAnnotation[]>;
|
|
20
|
+
show: () => Promise<void>;
|
|
21
|
+
hide: () => Promise<void>;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Cleanup function for React useEffect.
|
|
25
|
+
*/
|
|
26
|
+
declare function destroyCheckflow(): void;
|
|
27
|
+
|
|
28
|
+
export { destroyCheckflow, useCheckflowFeedback, useCheckflowInit };
|