@triagly/sdk 0.1.1-beta.1

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 ADDED
@@ -0,0 +1,451 @@
1
+ # @triagly/sdk
2
+
3
+ > JavaScript SDK for Triagly - Turn user feedback into GitHub issues instantly.
4
+
5
+ Lightweight (<10KB gzipped) browser widget that captures user feedback with screenshots and automatically creates GitHub issues.
6
+
7
+ ## Features
8
+
9
+ - 🎨 **Beautiful UI Widget** - Clean, customizable feedback form
10
+ - 📸 **Screenshot Capture** - Automatic page screenshots (with html2canvas)
11
+ - 🐛 **Console Log Capture** - Automatically captures browser console errors and warnings for debugging
12
+ - 🤖 **Bot Protection** - Cloudflare Turnstile integration to prevent spam
13
+ - 🔒 **Secure Authentication** - Uses publishable keys with optional hardened mode
14
+ - 📊 **Metadata Collection** - Browser, URL, viewport info automatically captured
15
+ - 🔐 **Privacy & Security** - Auto-sanitizes sensitive data (tokens, passwords, emails)
16
+ - ⚡ **Lightweight** - Minimal bundle size, no heavy dependencies
17
+ - 🎯 **TypeScript** - Full type definitions included
18
+
19
+ ## Installation
20
+
21
+ ### NPM
22
+
23
+ ```bash
24
+ npm install @triagly/sdk
25
+ # or
26
+ pnpm add @triagly/sdk
27
+ # or
28
+ yarn add @triagly/sdk
29
+ ```
30
+
31
+ ### CDN
32
+
33
+ ```html
34
+ <!-- Include Cloudflare Turnstile for bot protection -->
35
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
36
+
37
+ <!-- Include html2canvas for screenshot support (optional) -->
38
+ <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
39
+
40
+ <!-- Include Triagly SDK -->
41
+ <script src="https://unpkg.com/@triagly/sdk/dist/index.min.js"></script>
42
+ ```
43
+
44
+ ## Quick Start
45
+
46
+ ### Method 1: Simple Mode (Recommended for most users)
47
+
48
+ ```typescript
49
+ import Triagly from '@triagly/sdk';
50
+
51
+ const triagly = new Triagly({
52
+ publishableKey: 'pub_live_abc123',
53
+ turnstileSiteKey: 'your-turnstile-site-key',
54
+ });
55
+ ```
56
+
57
+ ### Method 2: Hardened Mode (For sensitive applications)
58
+
59
+ ```typescript
60
+ import Triagly from '@triagly/sdk';
61
+
62
+ const triagly = new Triagly({
63
+ publishableKey: 'pub_live_abc123',
64
+ turnstileSiteKey: 'your-turnstile-site-key',
65
+ getToken: async () => {
66
+ // Call your backend to get a hardened token
67
+ const res = await fetch('/api/triagly-token', {
68
+ method: 'POST',
69
+ headers: { Authorization: `Bearer ${userSessionToken}` }
70
+ });
71
+ const { token } = await res.json();
72
+ return token;
73
+ }
74
+ });
75
+ ```
76
+
77
+ ### Method 3: Auto-initialization (CDN)
78
+
79
+ ```html
80
+ <script>
81
+ window.TriaglyConfig = {
82
+ publishableKey: 'pub_live_abc123',
83
+ turnstileSiteKey: 'your-turnstile-site-key',
84
+ };
85
+ </script>
86
+ <script src="https://unpkg.com/@triagly/sdk/dist/index.min.js"></script>
87
+ ```
88
+
89
+ ### Method 4: React Example
90
+
91
+ ```tsx
92
+ import { useEffect, useRef } from 'react';
93
+ import Triagly from '@triagly/sdk';
94
+
95
+ function App() {
96
+ const triaglyRef = useRef<Triagly | null>(null);
97
+
98
+ useEffect(() => {
99
+ triaglyRef.current = new Triagly({
100
+ publishableKey: 'pub_live_abc123',
101
+ turnstileSiteKey: 'your-turnstile-site-key',
102
+ onSuccess: (feedbackId) => {
103
+ console.log('Feedback submitted:', feedbackId);
104
+ },
105
+ onError: (error) => {
106
+ console.error('Feedback error:', error);
107
+ },
108
+ onOpen: () => {
109
+ console.log('Widget opened');
110
+ },
111
+ onClose: () => {
112
+ console.log('Widget closed');
113
+ },
114
+ });
115
+
116
+ return () => {
117
+ triaglyRef.current?.destroy();
118
+ };
119
+ }, []);
120
+
121
+ return <div>Your App</div>;
122
+ }
123
+ ```
124
+
125
+ ## Configuration
126
+
127
+ ```typescript
128
+ interface TriaglyConfig {
129
+ // Required
130
+ publishableKey: string; // Your Triagly publishable key
131
+
132
+ // Optional - Authentication
133
+ getToken?: () => Promise<string>; // Callback for hardened mode
134
+ turnstileSiteKey?: string; // Cloudflare Turnstile site key (required for bot protection)
135
+
136
+ // Optional - API Configuration
137
+ apiUrl?: string; // Custom API URL (defaults to production)
138
+
139
+ // Optional - UI Customization
140
+ theme?: 'light' | 'dark' | 'auto';
141
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
142
+ buttonShape?: 'rounded' | 'circular' | 'square' | 'pill'; // Default: "rounded"
143
+ buttonText?: string; // Default: "🐛 Feedback"
144
+ placeholderText?: string; // Default: "Describe what happened..."
145
+ successMessage?: string;
146
+ errorMessage?: string;
147
+
148
+ // Optional - Callbacks
149
+ onSuccess?: (feedbackId: string) => void; // Called after successful submission
150
+ onError?: (error: Error) => void; // Called on submission error
151
+ onOpen?: () => void; // Called when widget opens
152
+ onClose?: () => void; // Called when widget closes
153
+
154
+ // Optional - Console Log Capture
155
+ captureConsole?: boolean; // Enable console log capture (default: true)
156
+ consoleLogLimit?: number; // Max logs to keep (default: 50)
157
+ consoleLogLevels?: ('error' | 'warn' | 'log')[]; // Which levels to capture (default: ['error', 'warn'])
158
+
159
+ // Optional - Custom Metadata
160
+ metadata?: Record<string, any>; // Additional metadata to include
161
+ }
162
+ ```
163
+
164
+ ## API
165
+
166
+ ### Constructor
167
+
168
+ ```typescript
169
+ const triagly = new Triagly(config: TriaglyConfig);
170
+ ```
171
+
172
+ ### Methods
173
+
174
+ #### `open()`
175
+ Programmatically open the feedback widget.
176
+
177
+ ```typescript
178
+ triagly.open();
179
+ ```
180
+
181
+ #### `close()`
182
+ Programmatically close the feedback widget.
183
+
184
+ ```typescript
185
+ triagly.close();
186
+ ```
187
+
188
+ #### `submit(data)`
189
+ Submit feedback programmatically without UI.
190
+
191
+ ```typescript
192
+ await triagly.submit({
193
+ title: 'Bug: Login button not working',
194
+ description: 'When I click the login button, nothing happens.',
195
+ reporterEmail: 'user@example.com',
196
+ tags: ['bug', 'login'],
197
+ });
198
+ ```
199
+
200
+ #### `destroy()`
201
+ Remove the widget and clean up event listeners.
202
+
203
+ ```typescript
204
+ triagly.destroy();
205
+ ```
206
+
207
+ ## Examples
208
+
209
+ ### Custom Button Trigger
210
+
211
+ ```html
212
+ <button id="custom-feedback-btn">Report Issue</button>
213
+
214
+ <script>
215
+ const triagly = new Triagly({
216
+ publishableKey: 'pub_live_abc123',
217
+ turnstileSiteKey: 'your-turnstile-site-key',
218
+ });
219
+
220
+ document.getElementById('custom-feedback-btn').onclick = () => {
221
+ triagly.open();
222
+ };
223
+ </script>
224
+ ```
225
+
226
+ ### With Custom Metadata
227
+
228
+ ```typescript
229
+ const triagly = new Triagly({
230
+ publishableKey: 'pub_live_abc123',
231
+ turnstileSiteKey: 'your-turnstile-site-key',
232
+ metadata: {
233
+ appVersion: '1.2.3',
234
+ environment: 'production',
235
+ userId: 'user-123',
236
+ },
237
+ });
238
+ ```
239
+
240
+ ### Programmatic Submission
241
+
242
+ ```typescript
243
+ const triagly = new Triagly({
244
+ publishableKey: 'pub_live_abc123',
245
+ turnstileSiteKey: 'your-turnstile-site-key',
246
+ });
247
+
248
+ // Submit without opening widget
249
+ try {
250
+ await triagly.submit({
251
+ title: 'Feature Request',
252
+ description: 'It would be great to have dark mode.',
253
+ reporterEmail: 'user@example.com',
254
+ tags: ['feature-request'],
255
+ });
256
+ console.log('Feedback sent!');
257
+ } catch (error) {
258
+ console.error('Failed:', error);
259
+ }
260
+ ```
261
+
262
+ ### Using Pre-built Themes
263
+
264
+ ```html
265
+ <!-- Dark theme -->
266
+ <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/dark.css">
267
+
268
+ <!-- Minimal theme -->
269
+ <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/minimal.css">
270
+
271
+ <!-- Gradient theme -->
272
+ <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/gradient.css">
273
+
274
+ <!-- Ocean theme -->
275
+ <link rel="stylesheet" href="https://unpkg.com/@triagly/sdk/themes/ocean.css">
276
+ ```
277
+
278
+ ### Custom Styling with CSS Variables
279
+
280
+ ```css
281
+ :root {
282
+ /* Customize colors easily */
283
+ --triagly-button-bg: #ff0066;
284
+ --triagly-button-bg-hover: #cc0052;
285
+ --triagly-modal-bg: #ffffff;
286
+ --triagly-modal-radius: 20px;
287
+ --triagly-btn-primary-bg: #ff0066;
288
+ }
289
+ ```
290
+
291
+ See [Styling Guide](./docs/guides/STYLING.md) for all available variables and more examples.
292
+
293
+ ## Screenshot Support
294
+
295
+ To enable screenshot capture, include html2canvas:
296
+
297
+ ```html
298
+ <script src="https://cdn.jsdelivr.net/npm/html2canvas@1.4.1/dist/html2canvas.min.js"></script>
299
+ ```
300
+
301
+ Or install via NPM and import in your bundle:
302
+
303
+ ```bash
304
+ npm install html2canvas
305
+ ```
306
+
307
+ ```typescript
308
+ import html2canvas from 'html2canvas';
309
+ (window as any).html2canvas = html2canvas;
310
+ ```
311
+
312
+ ## Console Log Capture
313
+
314
+ The SDK automatically captures browser console messages (errors and warnings by default) to help developers debug issues.
315
+
316
+ ### How It Works
317
+
318
+ - Intercepts `console.error`, `console.warn`, and optionally `console.log`
319
+ - Stores the last 50 messages in a circular buffer
320
+ - Includes stack traces for errors
321
+ - Automatically sanitizes sensitive data (tokens, passwords, emails)
322
+ - Sends logs with feedback submissions
323
+
324
+ ### Example Captured Logs
325
+
326
+ When a user reports "Login doesn't work", the SDK automatically includes:
327
+
328
+ ```
329
+ [14:30:15] ❌ ERROR: TypeError: Cannot read property 'submit' of undefined
330
+ at LoginForm.handleSubmit (login.js:42:15)
331
+
332
+ [14:30:10] ⚠️ WARN: Deprecated API used: oldAuthMethod()
333
+
334
+ [14:30:08] ❌ ERROR: Network request failed: POST /api/auth/login
335
+ ```
336
+
337
+ ### Privacy & Sanitization
338
+
339
+ The SDK automatically sanitizes:
340
+ - API keys and tokens (e.g., `token=***`)
341
+ - Passwords (e.g., `password=***`)
342
+ - Email addresses (e.g., `***@***.com`)
343
+ - JWT tokens (e.g., `jwt.***`)
344
+ - Credit card numbers
345
+ - GitHub tokens
346
+
347
+ ### Disable Console Capture
348
+
349
+ ```typescript
350
+ const triagly = new Triagly({
351
+ projectId: 'your-project-id',
352
+ apiUrl: 'https://your-api.com',
353
+ captureConsole: false, // Disable console capture
354
+ });
355
+ ```
356
+
357
+ ### Customize Console Capture
358
+
359
+ ```typescript
360
+ const triagly = new Triagly({
361
+ projectId: 'your-project-id',
362
+ apiUrl: 'https://your-api.com',
363
+ captureConsole: true,
364
+ consoleLogLimit: 100, // Keep last 100 logs
365
+ consoleLogLevels: ['error'], // Only capture errors
366
+ });
367
+ ```
368
+
369
+ ## Rate Limiting
370
+
371
+ The SDK automatically rate-limits submissions to 3 per 5 minutes per user (stored in localStorage).
372
+
373
+ ## Migration Guide
374
+
375
+ ### Upgrading from v0.0.x to v0.1.0
376
+
377
+ This release introduces **breaking changes** for improved security and bot protection.
378
+
379
+ #### What Changed
380
+
381
+ 1. **`projectId` → `publishableKey`**
382
+ - Old: `projectId: 'uuid-here'`
383
+ - New: `publishableKey: 'pub_live_abc123'`
384
+
385
+ 2. **`apiUrl` is now optional**
386
+ - The SDK now defaults to the production API
387
+ - Only set this if using a custom deployment
388
+
389
+ 3. **Turnstile bot protection**
390
+ - Add `turnstileSiteKey` to your config
391
+ - Include the Turnstile script in your HTML
392
+
393
+ #### Migration Steps
394
+
395
+ **Before:**
396
+ ```typescript
397
+ const triagly = new Triagly({
398
+ projectId: 'your-project-id',
399
+ apiUrl: 'https://your-project.supabase.co/functions/v1',
400
+ });
401
+ ```
402
+
403
+ **After:**
404
+ ```typescript
405
+ const triagly = new Triagly({
406
+ publishableKey: 'pub_live_abc123', // Get from dashboard
407
+ turnstileSiteKey: 'your-turnstile-site-key', // Get from Cloudflare
408
+ });
409
+ ```
410
+
411
+ **Don't forget to add Turnstile:**
412
+ ```html
413
+ <script src="https://challenges.cloudflare.com/turnstile/v0/api.js" async defer></script>
414
+ ```
415
+
416
+ #### Backward Compatibility
417
+
418
+ The SDK maintains backward compatibility with `projectId` for now, but will show a deprecation warning. Update to `publishableKey` as soon as possible.
419
+
420
+ ## Browser Support
421
+
422
+ - Chrome/Edge (latest 2 versions)
423
+ - Firefox (latest 2 versions)
424
+ - Safari (latest 2 versions)
425
+
426
+ ## Development
427
+
428
+ ```bash
429
+ # Install dependencies
430
+ pnpm install
431
+
432
+ # Build
433
+ pnpm build
434
+
435
+ # Watch mode
436
+ pnpm dev
437
+ ```
438
+
439
+ ## Documentation
440
+
441
+ - [Accessibility Guide](./docs/guides/ACCESSIBILITY.md) - WCAG 2.1 AA compliance & keyboard navigation
442
+ - [Callbacks Guide](./docs/guides/CALLBACKS.md) - Complete callback documentation
443
+ - [Console Capture Guide](./docs/guides/CONSOLE_CAPTURE.md) - Automatic console log capture
444
+ - [Styling Guide](./docs/guides/STYLING.md) - Customize button and modal styles
445
+ - [Local Testing Guide](./docs/guides/TEST_LOCALLY.md) - Test the package locally
446
+ - [Contributing Guide](./docs/contributing/CONTRIBUTING.md) - Contribution guidelines
447
+ - [Release Guide](./docs/contributing/RELEASE_GUIDE.md) - How to create releases
448
+
449
+ ## License
450
+
451
+ MIT
package/dist/api.d.ts ADDED
@@ -0,0 +1,17 @@
1
+ import { FeedbackData, FeedbackMetadata, FeedbackResponse } from './types';
2
+ export declare class TriaglyAPI {
3
+ private apiUrl;
4
+ private publishableKey;
5
+ private getToken?;
6
+ private turnstileSiteKey?;
7
+ constructor(publishableKey: string, apiUrl?: string, getToken?: () => Promise<string>, turnstileSiteKey?: string);
8
+ /**
9
+ * Get Turnstile token from widget if available
10
+ */
11
+ private getTurnstileToken;
12
+ /**
13
+ * Submit feedback with new authentication
14
+ */
15
+ submitFeedback(data: FeedbackData, metadata: FeedbackMetadata, turnstileToken?: string): Promise<FeedbackResponse>;
16
+ }
17
+ //# sourceMappingURL=api.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"api.d.ts","sourceRoot":"","sources":["../src/api.ts"],"names":[],"mappings":"AAEA,OAAO,EACL,YAAY,EACZ,gBAAgB,EAChB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAIjB,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,QAAQ,CAAC,CAAwB;IACzC,OAAO,CAAC,gBAAgB,CAAC,CAAS;gBAGhC,cAAc,EAAE,MAAM,EACtB,MAAM,CAAC,EAAE,MAAM,EACf,QAAQ,CAAC,EAAE,MAAM,OAAO,CAAC,MAAM,CAAC,EAChC,gBAAgB,CAAC,EAAE,MAAM;IAQ3B;;OAEG;YACW,iBAAiB;IA4B/B;;OAEG;IACG,cAAc,CAClB,IAAI,EAAE,YAAY,EAClB,QAAQ,EAAE,gBAAgB,EAC1B,cAAc,CAAC,EAAE,MAAM,GACtB,OAAO,CAAC,gBAAgB,CAAC;CA2E7B"}
@@ -0,0 +1,37 @@
1
+ import { TriaglyConfig, FeedbackData } from './types';
2
+ export declare class Triagly {
3
+ private config;
4
+ private widget;
5
+ private api;
6
+ private rateLimiter;
7
+ private consoleLogger;
8
+ constructor(config: TriaglyConfig);
9
+ /**
10
+ * Initialize the SDK
11
+ */
12
+ private init;
13
+ /**
14
+ * Handle feedback submission
15
+ */
16
+ private handleSubmit;
17
+ /**
18
+ * Programmatically open the feedback widget
19
+ */
20
+ open(): void;
21
+ /**
22
+ * Programmatically close the feedback widget
23
+ */
24
+ close(): void;
25
+ /**
26
+ * Submit feedback programmatically without UI
27
+ * Note: When Turnstile is enabled, you must use the widget UI or provide a token
28
+ */
29
+ submit(data: FeedbackData, turnstileToken?: string): Promise<void>;
30
+ /**
31
+ * Destroy the SDK instance
32
+ */
33
+ destroy(): void;
34
+ }
35
+ export * from './types';
36
+ export default Triagly;
37
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,aAAa,EAAE,YAAY,EAAE,MAAM,SAAS,CAAC;AAKtD,qBAAa,OAAO;IAClB,OAAO,CAAC,MAAM,CAAgB;IAC9B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,GAAG,CAAa;IACxB,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,aAAa,CAA8B;gBAEvC,MAAM,EAAE,aAAa;IAmDjC;;OAEG;IACH,OAAO,CAAC,IAAI;IAWZ;;OAEG;YACW,YAAY;IAgE1B;;OAEG;IACH,IAAI,IAAI,IAAI;IAIZ;;OAEG;IACH,KAAK,IAAI,IAAI;IAIb;;;OAGG;IACG,MAAM,CAAC,IAAI,EAAE,YAAY,EAAE,cAAc,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAqBxE;;OAEG;IACH,OAAO,IAAI,IAAI;CAKhB;AAGD,cAAc,SAAS,CAAC;AAWxB,eAAe,OAAO,CAAC"}