@limekex/bugreport-widget-sdk 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.
Files changed (42) hide show
  1. package/README.md +47 -0
  2. package/dist/index.d.ts +8 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +5 -0
  5. package/dist/index.js.map +1 -0
  6. package/dist/types/widget.types.d.ts +21 -0
  7. package/dist/types/widget.types.d.ts.map +1 -0
  8. package/dist/types/widget.types.js +2 -0
  9. package/dist/types/widget.types.js.map +1 -0
  10. package/dist/utils/apiClient.d.ts +10 -0
  11. package/dist/utils/apiClient.d.ts.map +1 -0
  12. package/dist/utils/apiClient.js +19 -0
  13. package/dist/utils/apiClient.js.map +1 -0
  14. package/dist/utils/consoleCapture.d.ts +34 -0
  15. package/dist/utils/consoleCapture.d.ts.map +1 -0
  16. package/dist/utils/consoleCapture.js +82 -0
  17. package/dist/utils/consoleCapture.js.map +1 -0
  18. package/dist/utils/networkCapture.d.ts +44 -0
  19. package/dist/utils/networkCapture.d.ts.map +1 -0
  20. package/dist/utils/networkCapture.js +138 -0
  21. package/dist/utils/networkCapture.js.map +1 -0
  22. package/dist/utils/payloadBuilder.d.ts +15 -0
  23. package/dist/utils/payloadBuilder.d.ts.map +1 -0
  24. package/dist/utils/payloadBuilder.js +51 -0
  25. package/dist/utils/payloadBuilder.js.map +1 -0
  26. package/dist/utils/screenshotCapture.d.ts +21 -0
  27. package/dist/utils/screenshotCapture.d.ts.map +1 -0
  28. package/dist/utils/screenshotCapture.js +85 -0
  29. package/dist/utils/screenshotCapture.js.map +1 -0
  30. package/dist/widget/button.d.ts +11 -0
  31. package/dist/widget/button.d.ts.map +1 -0
  32. package/dist/widget/button.js +33 -0
  33. package/dist/widget/button.js.map +1 -0
  34. package/dist/widget/init.d.ts +28 -0
  35. package/dist/widget/init.d.ts.map +1 -0
  36. package/dist/widget/init.js +102 -0
  37. package/dist/widget/init.js.map +1 -0
  38. package/dist/widget/modal.d.ts +20 -0
  39. package/dist/widget/modal.d.ts.map +1 -0
  40. package/dist/widget/modal.js +493 -0
  41. package/dist/widget/modal.js.map +1 -0
  42. package/package.json +64 -0
@@ -0,0 +1,493 @@
1
+ import { buildReportPayload } from '../utils/payloadBuilder';
2
+ import { submitReport } from '../utils/apiClient';
3
+ import { capturePageScreenshot } from '../utils/screenshotCapture';
4
+ const SUCCESS_AUTO_CLOSE_DELAY_MS = 4000;
5
+ const MODAL_ID = '__bugreport_modal__';
6
+ const OVERLAY_ID = '__bugreport_overlay__';
7
+ const STYLE_ID = '__bugreport_styles__';
8
+ // ── CSS ──────────────────────────────────────────────────────────────────────
9
+ // Injected once as a <style> tag so the modal has a polished, production-ready
10
+ // look without requiring a CSS framework or React.
11
+ function injectStyles() {
12
+ if (document.getElementById(STYLE_ID))
13
+ return;
14
+ const style = document.createElement('style');
15
+ style.id = STYLE_ID;
16
+ style.textContent = `
17
+ /* ── Overlay ─────────────────────────────────────────────── */
18
+ #${OVERLAY_ID} {
19
+ position: fixed; inset: 0;
20
+ background: rgba(0,0,0,0.5);
21
+ backdrop-filter: blur(2px);
22
+ z-index: 10000;
23
+ display: flex; align-items: center; justify-content: center;
24
+ padding: 16px;
25
+ animation: __br_fade_in 0.15s ease-out;
26
+ }
27
+ @keyframes __br_fade_in {
28
+ from { opacity: 0; }
29
+ to { opacity: 1; }
30
+ }
31
+
32
+ /* ── Modal panel ────────────────────────────────────────── */
33
+ #${MODAL_ID} {
34
+ background: #fff;
35
+ border-radius: 12px;
36
+ padding: 28px 24px 24px;
37
+ width: 100%;
38
+ max-width: 560px;
39
+ max-height: 90vh;
40
+ overflow-y: auto;
41
+ font-family: system-ui, -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
42
+ font-size: 14px;
43
+ color: #1f2937;
44
+ box-shadow: 0 25px 60px rgba(0,0,0,0.25), 0 0 0 1px rgba(0,0,0,0.05);
45
+ animation: __br_slide_up 0.2s ease-out;
46
+ }
47
+ @keyframes __br_slide_up {
48
+ from { opacity: 0; transform: translateY(12px) scale(0.98); }
49
+ to { opacity: 1; transform: translateY(0) scale(1); }
50
+ }
51
+
52
+ /* ── Header ─────────────────────────────────────────────── */
53
+ .__br_header {
54
+ display: flex;
55
+ justify-content: space-between;
56
+ align-items: center;
57
+ margin-bottom: 20px;
58
+ }
59
+ .__br_title {
60
+ margin: 0;
61
+ font-size: 18px;
62
+ font-weight: 700;
63
+ color: #111827;
64
+ }
65
+ .__br_close_btn {
66
+ background: none; border: none;
67
+ font-size: 18px; cursor: pointer;
68
+ color: #9ca3af;
69
+ width: 32px; height: 32px;
70
+ display: flex; align-items: center; justify-content: center;
71
+ border-radius: 6px;
72
+ transition: background 0.15s, color 0.15s;
73
+ }
74
+ .__br_close_btn:hover { background: #f3f4f6; color: #374151; }
75
+
76
+ /* ── Form fields ────────────────────────────────────────── */
77
+ .__br_field {
78
+ margin-bottom: 16px;
79
+ }
80
+ .__br_label {
81
+ display: block;
82
+ font-weight: 600;
83
+ margin-bottom: 5px;
84
+ color: #374151;
85
+ font-size: 13px;
86
+ }
87
+ .__br_required {
88
+ color: #dc2626;
89
+ margin-left: 2px;
90
+ }
91
+ .__br_input,
92
+ .__br_select,
93
+ .__br_textarea {
94
+ width: 100%;
95
+ box-sizing: border-box;
96
+ padding: 9px 12px;
97
+ border: 1px solid #d1d5db;
98
+ border-radius: 8px;
99
+ font-size: 13px;
100
+ font-family: inherit;
101
+ color: #1f2937;
102
+ background: #fff;
103
+ transition: border-color 0.15s, box-shadow 0.15s;
104
+ }
105
+ .__br_input:focus,
106
+ .__br_select:focus,
107
+ .__br_textarea:focus {
108
+ outline: none;
109
+ border-color: #e11d48;
110
+ box-shadow: 0 0 0 3px rgba(225,29,72,0.1);
111
+ }
112
+ .__br_textarea {
113
+ resize: vertical;
114
+ min-height: 60px;
115
+ }
116
+ .__br_select {
117
+ appearance: auto;
118
+ }
119
+ .__br_hint {
120
+ margin: 4px 0 0;
121
+ font-size: 12px;
122
+ color: #9ca3af;
123
+ }
124
+
125
+ /* ── Screenshot section ──────────────────────────────────── */
126
+ .__br_screenshot_row {
127
+ display: flex;
128
+ gap: 8px;
129
+ align-items: center;
130
+ flex-wrap: wrap;
131
+ }
132
+ .__br_capture_btn {
133
+ display: inline-flex;
134
+ align-items: center;
135
+ gap: 6px;
136
+ padding: 7px 14px;
137
+ background: #f3f4f6;
138
+ border: 1px solid #d1d5db;
139
+ border-radius: 8px;
140
+ font-size: 13px;
141
+ font-family: inherit;
142
+ cursor: pointer;
143
+ color: #374151;
144
+ transition: background 0.15s, border-color 0.15s;
145
+ white-space: nowrap;
146
+ }
147
+ .__br_capture_btn:hover { background: #e5e7eb; border-color: #9ca3af; }
148
+ .__br_capture_btn:disabled { opacity: 0.5; cursor: not-allowed; }
149
+ .__br_capture_preview {
150
+ margin-top: 8px;
151
+ max-width: 100%;
152
+ max-height: 120px;
153
+ border-radius: 6px;
154
+ border: 1px solid #e5e7eb;
155
+ }
156
+ .__br_or_divider {
157
+ font-size: 12px;
158
+ color: #9ca3af;
159
+ }
160
+
161
+ /* ── Status messages ─────────────────────────────────────── */
162
+ .__br_status_success {
163
+ margin-top: 12px;
164
+ padding: 10px 14px;
165
+ border-radius: 8px;
166
+ background: #d1fae5;
167
+ color: #065f46;
168
+ font-size: 13px;
169
+ }
170
+ .__br_status_success a { color: #065f46; font-weight: 600; }
171
+ .__br_status_error {
172
+ margin-top: 12px;
173
+ padding: 10px 14px;
174
+ border-radius: 8px;
175
+ background: #fee2e2;
176
+ color: #991b1b;
177
+ font-size: 13px;
178
+ }
179
+
180
+ /* ── Submit button ───────────────────────────────────────── */
181
+ .__br_submit_btn {
182
+ margin-top: 18px;
183
+ width: 100%;
184
+ padding: 11px 16px;
185
+ background: #e11d48;
186
+ color: #fff;
187
+ border: none;
188
+ border-radius: 8px;
189
+ font-size: 14px;
190
+ font-weight: 600;
191
+ font-family: inherit;
192
+ cursor: pointer;
193
+ transition: background 0.15s, transform 0.1s;
194
+ }
195
+ .__br_submit_btn:hover:not(:disabled) { background: #be123c; }
196
+ .__br_submit_btn:active:not(:disabled) { transform: scale(0.99); }
197
+ .__br_submit_btn:disabled {
198
+ background: #9ca3af;
199
+ cursor: not-allowed;
200
+ }
201
+
202
+ /* ── Responsive (narrow viewports) ──────────────────────── */
203
+ @media (max-width: 480px) {
204
+ #${MODAL_ID} {
205
+ padding: 20px 16px 16px;
206
+ border-radius: 12px 12px 0 0;
207
+ max-height: 95vh;
208
+ }
209
+ #${OVERLAY_ID} {
210
+ align-items: flex-end;
211
+ padding: 0;
212
+ }
213
+ }
214
+ `;
215
+ document.head.appendChild(style);
216
+ }
217
+ // ── Open / close ──────────────────────────────────────────────────────────────
218
+ /**
219
+ * Opens the bug report modal and wires up form submission.
220
+ *
221
+ * The modal is a plain DOM element with production-ready CSS injected into the
222
+ * page. No React or CSS framework required — works in any web app.
223
+ *
224
+ * Features:
225
+ * - Focus trap (Tab/Shift-Tab cycle within modal)
226
+ * - Animated overlay + slide-up entrance
227
+ * - Responsive layout (stacks on mobile)
228
+ * - "Capture current screen" button (html2canvas when available)
229
+ * - Accessible: aria roles, keyboard dismiss, label associations
230
+ */
231
+ export function openModal(config, callbacks) {
232
+ if (document.getElementById(MODAL_ID))
233
+ return;
234
+ injectStyles();
235
+ const overlay = document.createElement('div');
236
+ overlay.id = OVERLAY_ID;
237
+ const modal = document.createElement('div');
238
+ modal.id = MODAL_ID;
239
+ modal.setAttribute('role', 'dialog');
240
+ modal.setAttribute('aria-modal', 'true');
241
+ modal.setAttribute('aria-labelledby', '__bugreport_title__');
242
+ modal.innerHTML = buildFormHtml();
243
+ overlay.appendChild(modal);
244
+ document.body.appendChild(overlay);
245
+ // ── Close handlers ─────────────────────────────────────────────────────────
246
+ const closeBtn = document.getElementById('__bugreport_close__');
247
+ closeBtn?.addEventListener('click', () => closeModal(callbacks));
248
+ overlay.addEventListener('click', (e) => {
249
+ if (e.target === overlay)
250
+ closeModal(callbacks);
251
+ });
252
+ document.addEventListener('keydown', handleEscKey);
253
+ // ── Focus trap ─────────────────────────────────────────────────────────────
254
+ trapFocus(modal);
255
+ // ── Screenshot capture button ──────────────────────────────────────────────
256
+ const captureBtn = document.getElementById('__br_capture_btn__');
257
+ captureBtn?.addEventListener('click', async () => {
258
+ await handleCaptureScreenshot(captureBtn);
259
+ });
260
+ // ── Form submission ────────────────────────────────────────────────────────
261
+ const form = document.getElementById('__bugreport_form__');
262
+ form?.addEventListener('submit', async (e) => {
263
+ e.preventDefault();
264
+ await handleSubmit(form, config, callbacks);
265
+ });
266
+ // Focus the first input
267
+ const firstInput = modal.querySelector('input, select, textarea');
268
+ firstInput?.focus();
269
+ }
270
+ export function closeModal(callbacks) {
271
+ const overlay = document.getElementById(OVERLAY_ID);
272
+ if (overlay) {
273
+ overlay.style.animation = 'none';
274
+ overlay.style.opacity = '0';
275
+ overlay.style.transition = 'opacity 0.12s ease-in';
276
+ setTimeout(() => overlay.remove(), 120);
277
+ }
278
+ document.removeEventListener('keydown', handleEscKey);
279
+ callbacks?.onClose();
280
+ }
281
+ // ── Focus trap ────────────────────────────────────────────────────────────────
282
+ function trapFocus(container) {
283
+ container.addEventListener('keydown', (e) => {
284
+ if (e.key !== 'Tab')
285
+ return;
286
+ const focusable = container.querySelectorAll('input, select, textarea, button, [tabindex]:not([tabindex="-1"])');
287
+ if (focusable.length === 0)
288
+ return;
289
+ const first = focusable[0];
290
+ const last = focusable[focusable.length - 1];
291
+ if (e.shiftKey && document.activeElement === first) {
292
+ e.preventDefault();
293
+ last.focus();
294
+ }
295
+ else if (!e.shiftKey && document.activeElement === last) {
296
+ e.preventDefault();
297
+ first.focus();
298
+ }
299
+ });
300
+ }
301
+ // ── Internal helpers ──────────────────────────────────────────────────────────
302
+ function handleEscKey(e) {
303
+ if (e.key === 'Escape')
304
+ closeModal();
305
+ }
306
+ async function handleCaptureScreenshot(captureBtn) {
307
+ const preview = document.getElementById('__br_capture_preview__');
308
+ const fileInput = document.getElementById('__br_screenshot__');
309
+ const captureContainer = document.getElementById('__br_capture_data__');
310
+ captureBtn.setAttribute('disabled', 'true');
311
+ captureBtn.textContent = '📸 Capturing…';
312
+ try {
313
+ // Hide the modal overlay temporarily so it's not in the screenshot
314
+ const overlay = document.getElementById(OVERLAY_ID);
315
+ if (overlay)
316
+ overlay.style.display = 'none';
317
+ const dataUrl = await capturePageScreenshot();
318
+ if (overlay)
319
+ overlay.style.display = '';
320
+ if (dataUrl && preview && captureContainer) {
321
+ preview.src = dataUrl;
322
+ preview.style.display = 'block';
323
+ captureContainer.value = dataUrl;
324
+ // Clear the file input so the capture takes precedence
325
+ if (fileInput)
326
+ fileInput.value = '';
327
+ }
328
+ }
329
+ catch {
330
+ // Silently fail — the user can still upload manually
331
+ }
332
+ captureBtn.removeAttribute('disabled');
333
+ captureBtn.textContent = '📸 Capture screen';
334
+ }
335
+ async function handleSubmit(form, config, callbacks) {
336
+ setFormState(form, 'loading');
337
+ try {
338
+ const values = collectFormValues(form);
339
+ const formData = buildReportPayload({
340
+ summary: values.summary,
341
+ severity: values.severity,
342
+ whatHappened: values.whatHappened,
343
+ expectedResult: values.expectedResult,
344
+ actualResult: values.actualResult,
345
+ stepsToReproduce: values.stepsToReproduce,
346
+ notes: values.notes || undefined,
347
+ environment: config.environment,
348
+ }, config);
349
+ // Attach screenshot — prefer captured screenshot, fall back to file upload
350
+ if (values.capturedScreenshot) {
351
+ const blob = dataUrlToBlob(values.capturedScreenshot);
352
+ formData.append('screenshot', blob, 'screenshot.png');
353
+ }
354
+ else if (values.screenshot) {
355
+ formData.append('screenshot', values.screenshot);
356
+ }
357
+ const result = await submitReport({ apiBaseUrl: config.apiBaseUrl, formData });
358
+ setFormState(form, 'success', result.githubIssueUrl);
359
+ }
360
+ catch (err) {
361
+ const message = err instanceof Error ? err.message : 'Unknown error';
362
+ setFormState(form, 'error', message);
363
+ }
364
+ }
365
+ function dataUrlToBlob(dataUrl) {
366
+ const [header, base64] = dataUrl.split(',');
367
+ const mime = header.match(/:(.*?);/)?.[1] ?? 'image/png';
368
+ const bytes = atob(base64);
369
+ const array = new Uint8Array(bytes.length);
370
+ for (let i = 0; i < bytes.length; i++)
371
+ array[i] = bytes.charCodeAt(i);
372
+ return new Blob([array], { type: mime });
373
+ }
374
+ function collectFormValues(form) {
375
+ const data = new FormData(form);
376
+ const screenshot = form.querySelector('#__br_screenshot__')?.files?.[0] ?? null;
377
+ const capturedScreenshot = form.querySelector('#__br_capture_data__')?.value ?? '';
378
+ return {
379
+ summary: String(data.get('summary') ?? ''),
380
+ severity: String(data.get('severity') ?? 'medium'),
381
+ whatHappened: String(data.get('whatHappened') ?? ''),
382
+ expectedResult: String(data.get('expectedResult') ?? ''),
383
+ actualResult: String(data.get('actualResult') ?? ''),
384
+ stepsToReproduce: String(data.get('stepsToReproduce') ?? ''),
385
+ notes: String(data.get('notes') ?? ''),
386
+ screenshot,
387
+ capturedScreenshot,
388
+ };
389
+ }
390
+ function setFormState(form, state, message) {
391
+ const submitBtn = form.querySelector('#__bugreport_submit__');
392
+ const statusEl = document.getElementById('__bugreport_status__');
393
+ if (!submitBtn || !statusEl)
394
+ return;
395
+ statusEl.innerHTML = '';
396
+ statusEl.className = '';
397
+ submitBtn.disabled = false;
398
+ if (state === 'loading') {
399
+ submitBtn.disabled = true;
400
+ submitBtn.textContent = 'Submitting…';
401
+ }
402
+ else if (state === 'success') {
403
+ submitBtn.textContent = 'Submit bug report';
404
+ statusEl.className = '__br_status_success';
405
+ statusEl.innerHTML = `✅ Bug report submitted! <a href="${message}" target="_blank" rel="noopener">View GitHub issue →</a>`;
406
+ setTimeout(() => closeModal(), SUCCESS_AUTO_CLOSE_DELAY_MS);
407
+ }
408
+ else if (state === 'error') {
409
+ submitBtn.textContent = 'Submit bug report';
410
+ statusEl.className = '__br_status_error';
411
+ statusEl.textContent = `❌ ${message ?? 'Something went wrong. Please try again.'}`;
412
+ }
413
+ }
414
+ function buildFormHtml() {
415
+ return `
416
+ <div class="__br_header">
417
+ <h2 id="__bugreport_title__" class="__br_title">🐛 Report a bug</h2>
418
+ <button id="__bugreport_close__" type="button" aria-label="Close" class="__br_close_btn">✕</button>
419
+ </div>
420
+
421
+ <form id="__bugreport_form__" novalidate>
422
+
423
+ <div class="__br_field">
424
+ <label for="__br_summary__" class="__br_label">Summary<span class="__br_required">*</span></label>
425
+ <input id="__br_summary__" name="summary" type="text" required maxlength="200"
426
+ placeholder="One-line summary of the bug" class="__br_input" />
427
+ </div>
428
+
429
+ <div class="__br_field">
430
+ <label for="__br_severity__" class="__br_label">Severity<span class="__br_required">*</span></label>
431
+ <select id="__br_severity__" name="severity" required class="__br_select">
432
+ <option value="low">Low — minor / cosmetic</option>
433
+ <option value="medium" selected>Medium — feature partially broken</option>
434
+ <option value="high">High — major feature broken</option>
435
+ <option value="blocker">Blocker — app unusable / data loss</option>
436
+ </select>
437
+ </div>
438
+
439
+ <div class="__br_field">
440
+ <label for="__br_whatHappened__" class="__br_label">What happened?<span class="__br_required">*</span></label>
441
+ <textarea id="__br_whatHappened__" name="whatHappened" rows="3"
442
+ placeholder="Describe what you observed…" required class="__br_textarea"></textarea>
443
+ </div>
444
+
445
+ <div class="__br_field">
446
+ <label for="__br_expectedResult__" class="__br_label">Expected result<span class="__br_required">*</span></label>
447
+ <textarea id="__br_expectedResult__" name="expectedResult" rows="2"
448
+ placeholder="What should have happened?" required class="__br_textarea"></textarea>
449
+ </div>
450
+
451
+ <div class="__br_field">
452
+ <label for="__br_actualResult__" class="__br_label">Actual result<span class="__br_required">*</span></label>
453
+ <textarea id="__br_actualResult__" name="actualResult" rows="2"
454
+ placeholder="What actually happened?" required class="__br_textarea"></textarea>
455
+ </div>
456
+
457
+ <div class="__br_field">
458
+ <label for="__br_stepsToReproduce__" class="__br_label">Steps to reproduce<span class="__br_required">*</span></label>
459
+ <textarea id="__br_stepsToReproduce__" name="stepsToReproduce" rows="4"
460
+ placeholder="1. Go to /login\n2. Enter credentials\n3. Click Submit" required class="__br_textarea"></textarea>
461
+ </div>
462
+
463
+ <div class="__br_field">
464
+ <label class="__br_label">Screenshot (optional)</label>
465
+ <div class="__br_screenshot_row">
466
+ <button id="__br_capture_btn__" type="button" class="__br_capture_btn">📸 Capture screen</button>
467
+ <span class="__br_or_divider">or</span>
468
+ <input id="__br_screenshot__" name="screenshot" type="file"
469
+ accept="image/png,image/jpeg,image/webp,image/gif"
470
+ style="font-size:13px;color:#374151;max-width:200px;" />
471
+ </div>
472
+ <input id="__br_capture_data__" type="hidden" value="" />
473
+ <img id="__br_capture_preview__" alt="Captured screenshot preview"
474
+ class="__br_capture_preview" style="display:none;" />
475
+ <p class="__br_hint">PNG, JPG, WebP or GIF · max 5 MB</p>
476
+ </div>
477
+
478
+ <div class="__br_field">
479
+ <label for="__br_notes__" class="__br_label">Additional notes (optional)</label>
480
+ <textarea id="__br_notes__" name="notes" rows="2"
481
+ placeholder="Anything else worth mentioning?" class="__br_textarea"></textarea>
482
+ </div>
483
+
484
+ <div id="__bugreport_status__"></div>
485
+
486
+ <button id="__bugreport_submit__" type="submit" class="__br_submit_btn">
487
+ Submit bug report
488
+ </button>
489
+
490
+ </form>
491
+ `;
492
+ }
493
+ //# sourceMappingURL=modal.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"modal.js","sourceRoot":"","sources":["../../src/widget/modal.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAC7D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EAAE,qBAAqB,EAAE,MAAM,4BAA4B,CAAC;AAEnE,MAAM,2BAA2B,GAAG,IAAI,CAAC;AACzC,MAAM,QAAQ,GAAG,qBAAqB,CAAC;AACvC,MAAM,UAAU,GAAG,uBAAuB,CAAC;AAC3C,MAAM,QAAQ,GAAG,sBAAsB,CAAC;AAMxC,gFAAgF;AAChF,+EAA+E;AAC/E,mDAAmD;AAEnD,SAAS,YAAY;IACnB,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAC9C,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,OAAO,CAAC,CAAC;IAC9C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,WAAW,GAAG;;OAEf,UAAU;;;;;;;;;;;;;;;OAeV,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;SA2KN,QAAQ;;;;;SAKR,UAAU;;;;;GAKhB,CAAC;IACF,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;AACnC,CAAC;AAED,iFAAiF;AAEjF;;;;;;;;;;;;GAYG;AACH,MAAM,UAAU,SAAS,CAAC,MAAyB,EAAE,SAAyB;IAC5E,IAAI,QAAQ,CAAC,cAAc,CAAC,QAAQ,CAAC;QAAE,OAAO;IAE9C,YAAY,EAAE,CAAC;IAEf,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC9C,OAAO,CAAC,EAAE,GAAG,UAAU,CAAC;IAExB,MAAM,KAAK,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC;IAC5C,KAAK,CAAC,EAAE,GAAG,QAAQ,CAAC;IACpB,KAAK,CAAC,YAAY,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;IACrC,KAAK,CAAC,YAAY,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;IACzC,KAAK,CAAC,YAAY,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC;IAE7D,KAAK,CAAC,SAAS,GAAG,aAAa,EAAE,CAAC;IAClC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,CAAC;IAC3B,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;IAEnC,8EAA8E;IAC9E,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,qBAAqB,CAAC,CAAC;IAChE,QAAQ,EAAE,gBAAgB,CAAC,OAAO,EAAE,GAAG,EAAE,CAAC,UAAU,CAAC,SAAS,CAAC,CAAC,CAAC;IAEjE,OAAO,CAAC,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EAAE,EAAE;QACtC,IAAI,CAAC,CAAC,MAAM,KAAK,OAAO;YAAE,UAAU,CAAC,SAAS,CAAC,CAAC;IAClD,CAAC,CAAC,CAAC;IAEH,QAAQ,CAAC,gBAAgB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IAEnD,8EAA8E;IAC9E,SAAS,CAAC,KAAK,CAAC,CAAC;IAEjB,8EAA8E;IAC9E,MAAM,UAAU,GAAG,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAAC,CAAC;IACjE,UAAU,EAAE,gBAAgB,CAAC,OAAO,EAAE,KAAK,IAAI,EAAE;QAC/C,MAAM,uBAAuB,CAAC,UAAU,CAAC,CAAC;IAC5C,CAAC,CAAC,CAAC;IAEH,8EAA8E;IAC9E,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,CAAC,oBAAoB,CAA2B,CAAC;IACrF,IAAI,EAAE,gBAAgB,CAAC,QAAQ,EAAE,KAAK,EAAE,CAAC,EAAE,EAAE;QAC3C,CAAC,CAAC,cAAc,EAAE,CAAC;QACnB,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,SAAS,CAAC,CAAC;IAC9C,CAAC,CAAC,CAAC;IAEH,wBAAwB;IACxB,MAAM,UAAU,GAAG,KAAK,CAAC,aAAa,CAAC,yBAAyB,CAAuB,CAAC;IACxF,UAAU,EAAE,KAAK,EAAE,CAAC;AACtB,CAAC;AAED,MAAM,UAAU,UAAU,CAAC,SAA0B;IACnD,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;IACpD,IAAI,OAAO,EAAE,CAAC;QACZ,OAAO,CAAC,KAAK,CAAC,SAAS,GAAG,MAAM,CAAC;QACjC,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,GAAG,CAAC;QAC5B,OAAO,CAAC,KAAK,CAAC,UAAU,GAAG,uBAAuB,CAAC;QACnD,UAAU,CAAC,GAAG,EAAE,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,GAAG,CAAC,CAAC;IAC1C,CAAC;IACD,QAAQ,CAAC,mBAAmB,CAAC,SAAS,EAAE,YAAY,CAAC,CAAC;IACtD,SAAS,EAAE,OAAO,EAAE,CAAC;AACvB,CAAC;AAED,iFAAiF;AAEjF,SAAS,SAAS,CAAC,SAAsB;IACvC,SAAS,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QAC1C,IAAI,CAAC,CAAC,GAAG,KAAK,KAAK;YAAE,OAAO;QAE5B,MAAM,SAAS,GAAG,SAAS,CAAC,gBAAgB,CAC1C,kEAAkE,CACnE,CAAC;QACF,IAAI,SAAS,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO;QAEnC,MAAM,KAAK,GAAG,SAAS,CAAC,CAAC,CAAC,CAAC;QAC3B,MAAM,IAAI,GAAG,SAAS,CAAC,SAAS,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QAE7C,IAAI,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,aAAa,KAAK,KAAK,EAAE,CAAC;YACnD,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,IAAI,CAAC,KAAK,EAAE,CAAC;QACf,CAAC;aAAM,IAAI,CAAC,CAAC,CAAC,QAAQ,IAAI,QAAQ,CAAC,aAAa,KAAK,IAAI,EAAE,CAAC;YAC1D,CAAC,CAAC,cAAc,EAAE,CAAC;YACnB,KAAK,CAAC,KAAK,EAAE,CAAC;QAChB,CAAC;IACH,CAAC,CAAC,CAAC;AACL,CAAC;AAED,iFAAiF;AAEjF,SAAS,YAAY,CAAC,CAAgB;IACpC,IAAI,CAAC,CAAC,GAAG,KAAK,QAAQ;QAAE,UAAU,EAAE,CAAC;AACvC,CAAC;AAED,KAAK,UAAU,uBAAuB,CAAC,UAAuB;IAC5D,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,wBAAwB,CAA4B,CAAC;IAC7F,MAAM,SAAS,GAAG,QAAQ,CAAC,cAAc,CAAC,mBAAmB,CAA4B,CAAC;IAC1F,MAAM,gBAAgB,GAAG,QAAQ,CAAC,cAAc,CAAC,qBAAqB,CAA4B,CAAC;IAEnG,UAAU,CAAC,YAAY,CAAC,UAAU,EAAE,MAAM,CAAC,CAAC;IAC5C,UAAU,CAAC,WAAW,GAAG,eAAe,CAAC;IAEzC,IAAI,CAAC;QACH,mEAAmE;QACnE,MAAM,OAAO,GAAG,QAAQ,CAAC,cAAc,CAAC,UAAU,CAAC,CAAC;QACpD,IAAI,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;QAE5C,MAAM,OAAO,GAAG,MAAM,qBAAqB,EAAE,CAAC;QAE9C,IAAI,OAAO;YAAE,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,EAAE,CAAC;QAExC,IAAI,OAAO,IAAI,OAAO,IAAI,gBAAgB,EAAE,CAAC;YAC3C,OAAO,CAAC,GAAG,GAAG,OAAO,CAAC;YACtB,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,OAAO,CAAC;YAChC,gBAAgB,CAAC,KAAK,GAAG,OAAO,CAAC;YACjC,uDAAuD;YACvD,IAAI,SAAS;gBAAE,SAAS,CAAC,KAAK,GAAG,EAAE,CAAC;QACtC,CAAC;IACH,CAAC;IAAC,MAAM,CAAC;QACP,qDAAqD;IACvD,CAAC;IAED,UAAU,CAAC,eAAe,CAAC,UAAU,CAAC,CAAC;IACvC,UAAU,CAAC,WAAW,GAAG,mBAAmB,CAAC;AAC/C,CAAC;AAED,KAAK,UAAU,YAAY,CACzB,IAAqB,EACrB,MAAyB,EACzB,SAAyB;IAEzB,YAAY,CAAC,IAAI,EAAE,SAAS,CAAC,CAAC;IAE9B,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,iBAAiB,CAAC,IAAI,CAAC,CAAC;QACvC,MAAM,QAAQ,GAAG,kBAAkB,CACjC;YACE,OAAO,EAAE,MAAM,CAAC,OAAO;YACvB,QAAQ,EAAE,MAAM,CAAC,QAAiD;YAClE,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,cAAc,EAAE,MAAM,CAAC,cAAc;YACrC,YAAY,EAAE,MAAM,CAAC,YAAY;YACjC,gBAAgB,EAAE,MAAM,CAAC,gBAAgB;YACzC,KAAK,EAAE,MAAM,CAAC,KAAK,IAAI,SAAS;YAChC,WAAW,EAAE,MAAM,CAAC,WAAW;SAChC,EACD,MAAM,CACP,CAAC;QAEF,2EAA2E;QAC3E,IAAI,MAAM,CAAC,kBAAkB,EAAE,CAAC;YAC9B,MAAM,IAAI,GAAG,aAAa,CAAC,MAAM,CAAC,kBAAkB,CAAC,CAAC;YACtD,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,IAAI,EAAE,gBAAgB,CAAC,CAAC;QACxD,CAAC;aAAM,IAAI,MAAM,CAAC,UAAU,EAAE,CAAC;YAC7B,QAAQ,CAAC,MAAM,CAAC,YAAY,EAAE,MAAM,CAAC,UAAU,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,YAAY,CAAC,EAAE,UAAU,EAAE,MAAM,CAAC,UAAU,EAAE,QAAQ,EAAE,CAAC,CAAC;QAE/E,YAAY,CAAC,IAAI,EAAE,SAAS,EAAE,MAAM,CAAC,cAAc,CAAC,CAAC;IACvD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,OAAO,GAAG,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,eAAe,CAAC;QACrE,YAAY,CAAC,IAAI,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC;IACvC,CAAC;AACH,CAAC;AAED,SAAS,aAAa,CAAC,OAAe;IACpC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,SAAS,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,WAAW,CAAC;IACzD,MAAM,KAAK,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC3B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC;IAC3C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE;QAAE,KAAK,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IACtE,OAAO,IAAI,IAAI,CAAC,CAAC,KAAK,CAAC,EAAE,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAC;AAC3C,CAAC;AAED,SAAS,iBAAiB,CAAC,IAAqB;IAW9C,MAAM,IAAI,GAAG,IAAI,QAAQ,CAAC,IAAI,CAAC,CAAC;IAChC,MAAM,UAAU,GAAI,IAAI,CAAC,aAAa,CAAC,oBAAoB,CAAsB,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,IAAI,IAAI,CAAC;IACtG,MAAM,kBAAkB,GAAI,IAAI,CAAC,aAAa,CAAC,sBAAsB,CAAsB,EAAE,KAAK,IAAI,EAAE,CAAC;IACzG,OAAO;QACL,OAAO,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC;QAC1C,QAAQ,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,IAAI,QAAQ,CAAC;QAClD,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QACpD,cAAc,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,gBAAgB,CAAC,IAAI,EAAE,CAAC;QACxD,YAAY,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,cAAc,CAAC,IAAI,EAAE,CAAC;QACpD,gBAAgB,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,kBAAkB,CAAC,IAAI,EAAE,CAAC;QAC5D,KAAK,EAAE,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;QACtC,UAAU;QACV,kBAAkB;KACnB,CAAC;AACJ,CAAC;AAID,SAAS,YAAY,CAAC,IAAqB,EAAE,KAAgB,EAAE,OAAgB;IAC7E,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAAC,uBAAuB,CAA6B,CAAC;IAC1F,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAAC;IAEjE,IAAI,CAAC,SAAS,IAAI,CAAC,QAAQ;QAAE,OAAO;IAEpC,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC;IACxB,QAAQ,CAAC,SAAS,GAAG,EAAE,CAAC;IACxB,SAAS,CAAC,QAAQ,GAAG,KAAK,CAAC;IAE3B,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,SAAS,CAAC,QAAQ,GAAG,IAAI,CAAC;QAC1B,SAAS,CAAC,WAAW,GAAG,aAAa,CAAC;IACxC,CAAC;SAAM,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QAC/B,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC;QAC5C,QAAQ,CAAC,SAAS,GAAG,qBAAqB,CAAC;QAC3C,QAAQ,CAAC,SAAS,GAAG,oCAAoC,OAAO,0DAA0D,CAAC;QAC3H,UAAU,CAAC,GAAG,EAAE,CAAC,UAAU,EAAE,EAAE,2BAA2B,CAAC,CAAC;IAC9D,CAAC;SAAM,IAAI,KAAK,KAAK,OAAO,EAAE,CAAC;QAC7B,SAAS,CAAC,WAAW,GAAG,mBAAmB,CAAC;QAC5C,QAAQ,CAAC,SAAS,GAAG,mBAAmB,CAAC;QACzC,QAAQ,CAAC,WAAW,GAAG,KAAK,OAAO,IAAI,yCAAyC,EAAE,CAAC;IACrF,CAAC;AACH,CAAC;AAED,SAAS,aAAa;IACpB,OAAO;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4EN,CAAC;AACJ,CAAC"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@limekex/bugreport-widget-sdk",
3
+ "version": "0.1.0",
4
+ "description": "Browser SDK for embedding the Stage Bug Reporter widget into staging/UAT applications",
5
+ "keywords": [
6
+ "bug-reporter",
7
+ "bug-tracking",
8
+ "staging",
9
+ "testing",
10
+ "github-issues",
11
+ "qa",
12
+ "uat"
13
+ ],
14
+ "author": "limekex",
15
+ "license": "MIT",
16
+ "repository": {
17
+ "type": "git",
18
+ "url": "https://github.com/limekex/bugreport-platform.git",
19
+ "directory": "packages/widget-sdk"
20
+ },
21
+ "main": "./dist/index.js",
22
+ "module": "./dist/index.mjs",
23
+ "types": "./dist/index.d.ts",
24
+ "files": [
25
+ "dist",
26
+ "README.md"
27
+ ],
28
+ "exports": {
29
+ ".": {
30
+ "import": "./dist/index.mjs",
31
+ "require": "./dist/index.js",
32
+ "types": "./dist/index.d.ts"
33
+ }
34
+ },
35
+ "sideEffects": false,
36
+ "scripts": {
37
+ "build": "tsc --project tsconfig.json",
38
+ "typecheck": "tsc --noEmit",
39
+ "dev": "tsc --watch --noEmit",
40
+ "test": "vitest run",
41
+ "lint": "eslint \"src/**/*.ts\""
42
+ },
43
+ "dependencies": {
44
+ "@bugreport/shared-types": "workspace:*"
45
+ },
46
+ "devDependencies": {
47
+ "@types/node": "^20.12.7",
48
+ "jsdom": "^29.0.1",
49
+ "typescript": "^5.4.5",
50
+ "vitest": "^1.5.0"
51
+ },
52
+ "peerDependencies": {
53
+ "react": ">=18",
54
+ "react-dom": ">=18"
55
+ },
56
+ "peerDependenciesMeta": {
57
+ "react": {
58
+ "optional": true
59
+ },
60
+ "react-dom": {
61
+ "optional": true
62
+ }
63
+ }
64
+ }