@checkflow/sdk 1.0.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.
@@ -0,0 +1,299 @@
1
+ /**
2
+ * CheckFlow SDK Types
3
+ */
4
+ export interface CheckFlowOptions {
5
+ /** API endpoint URL (default: https://api.checkflow.io) */
6
+ apiUrl?: string;
7
+ /** Project ID for feedback association */
8
+ projectId?: string;
9
+ /** Enable/disable the floating feedback button */
10
+ showWidget?: boolean;
11
+ /** Widget position */
12
+ widgetPosition?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
13
+ /** Custom widget button text */
14
+ widgetButtonText?: string;
15
+ /** Primary color for the widget (hex format) */
16
+ primaryColor?: string;
17
+ /** Enable automatic error capture */
18
+ captureErrors?: boolean;
19
+ /** Enable console log capture */
20
+ captureConsole?: boolean;
21
+ /** Enable network request capture */
22
+ captureNetwork?: boolean;
23
+ /** Enable performance metrics capture */
24
+ capturePerformance?: boolean;
25
+ /** Enable session recording */
26
+ captureSessionRecording?: boolean;
27
+ /** Privacy configuration for automatic PII masking */
28
+ privacy?: {
29
+ enabled?: boolean;
30
+ autoMask?: {
31
+ emails?: boolean;
32
+ creditCards?: boolean;
33
+ phoneNumbers?: boolean;
34
+ passwords?: boolean;
35
+ };
36
+ excludeSelectors?: string[];
37
+ };
38
+ /** Maximum console entries to capture */
39
+ maxConsoleEntries?: number;
40
+ /** Maximum network entries to capture */
41
+ maxNetworkEntries?: number;
42
+ /** User identification */
43
+ user?: UserInfo;
44
+ /** Custom metadata to include with all feedbacks */
45
+ metadata?: Record<string, any>;
46
+ /** Callback before feedback is submitted */
47
+ beforeSubmit?: (feedback: FeedbackData) => FeedbackData | false;
48
+ /** Callback after feedback is submitted */
49
+ onSubmit?: (result: SubmitResult) => void;
50
+ /** Callback on error */
51
+ onError?: (error: Error) => void;
52
+ /** Enable debug mode */
53
+ debug?: boolean;
54
+ /** Custom CSS for widget */
55
+ customStyles?: string;
56
+ /** Localization */
57
+ locale?: 'en' | 'fr' | 'es' | 'de';
58
+ /** Custom translations */
59
+ translations?: Partial<Translations>;
60
+ /** Enable analytics tracking */
61
+ enableAnalytics?: boolean;
62
+ /** Analytics configuration */
63
+ analytics?: {
64
+ trackClicks?: boolean;
65
+ trackScrolling?: boolean;
66
+ trackFormInteractions?: boolean;
67
+ trackErrors?: boolean;
68
+ trackPerformance?: boolean;
69
+ batchSize?: number;
70
+ batchTimeout?: number;
71
+ debug?: boolean;
72
+ };
73
+ }
74
+ export interface UserInfo {
75
+ id?: string;
76
+ email?: string;
77
+ name?: string;
78
+ avatar?: string;
79
+ [key: string]: any;
80
+ }
81
+ export type FeedbackType = 'bug' | 'feature_request' | 'improvement' | 'question' | 'other';
82
+ export type FeedbackPriority = 'low' | 'medium' | 'high' | 'critical';
83
+ export interface FeedbackData {
84
+ /** Feedback title */
85
+ title: string;
86
+ /** Detailed description */
87
+ description?: string;
88
+ /** Feedback type */
89
+ type: FeedbackType;
90
+ /** Priority level */
91
+ priority?: FeedbackPriority;
92
+ /** Tags/labels */
93
+ tags?: string[];
94
+ /** User info override */
95
+ user?: UserInfo;
96
+ /** Custom metadata */
97
+ metadata?: Record<string, any>;
98
+ /** Include screenshot */
99
+ includeScreenshot?: boolean;
100
+ /** Include console logs */
101
+ includeConsoleLogs?: boolean;
102
+ /** Include network logs */
103
+ includeNetworkLogs?: boolean;
104
+ /** Include session recording */
105
+ includeSessionRecording?: boolean;
106
+ /** Annotations on screenshot */
107
+ annotations?: Annotation[];
108
+ }
109
+ export interface Annotation {
110
+ type: 'rectangle' | 'arrow' | 'text' | 'highlight';
111
+ x: number;
112
+ y: number;
113
+ width?: number;
114
+ height?: number;
115
+ color?: string;
116
+ text?: string;
117
+ }
118
+ export interface CaptureOptions {
119
+ /** Capture full page or viewport only */
120
+ fullPage?: boolean;
121
+ /** Screenshot quality (1-100) */
122
+ quality?: number;
123
+ /** Delay before capture (ms) */
124
+ delay?: number;
125
+ /** Elements to hide (CSS selectors) */
126
+ hideElements?: string[];
127
+ /** Elements to mask (CSS selectors) - replaces content with placeholder */
128
+ maskElements?: string[];
129
+ /** Include console logs */
130
+ includeConsole?: boolean;
131
+ /** Include network logs */
132
+ includeNetwork?: boolean;
133
+ /** Include performance metrics */
134
+ includePerformance?: boolean;
135
+ }
136
+ export interface CaptureResult {
137
+ /** Base64 encoded screenshot */
138
+ screenshot?: string;
139
+ /** Screenshot URL (after upload) */
140
+ screenshotUrl?: string;
141
+ /** Console log entries */
142
+ consoleLogs?: ConsoleEntry[];
143
+ /** Network request entries */
144
+ networkLogs?: NetworkEntry[];
145
+ /** Performance metrics */
146
+ performance?: PerformanceMetrics;
147
+ /** Page context */
148
+ context: PageContext;
149
+ /** Captured at timestamp */
150
+ capturedAt: string;
151
+ }
152
+ export interface ConsoleEntry {
153
+ level: 'log' | 'info' | 'warn' | 'error' | 'debug';
154
+ message: string;
155
+ timestamp: string;
156
+ stack?: string;
157
+ }
158
+ export interface NetworkEntry {
159
+ url: string;
160
+ method: string;
161
+ status?: number;
162
+ statusText?: string;
163
+ duration?: number;
164
+ size?: number;
165
+ type?: string;
166
+ timestamp: string;
167
+ error?: string;
168
+ }
169
+ export interface PerformanceMetrics {
170
+ /** Page load time (ms) */
171
+ loadTime?: number;
172
+ /** DOM content loaded time (ms) */
173
+ domContentLoaded?: number;
174
+ /** First contentful paint (ms) */
175
+ firstContentfulPaint?: number;
176
+ /** Largest contentful paint (ms) */
177
+ largestContentfulPaint?: number;
178
+ /** Time to interactive (ms) */
179
+ timeToInteractive?: number;
180
+ /** Cumulative layout shift */
181
+ cumulativeLayoutShift?: number;
182
+ /** First input delay (ms) */
183
+ firstInputDelay?: number;
184
+ /** Memory usage (MB) */
185
+ memoryUsage?: number;
186
+ }
187
+ export interface PageContext {
188
+ /** Current URL */
189
+ url: string;
190
+ /** Page title */
191
+ title: string;
192
+ /** Viewport dimensions */
193
+ viewport: {
194
+ width: number;
195
+ height: number;
196
+ };
197
+ /** User agent string */
198
+ userAgent: string;
199
+ /** Browser info */
200
+ browser: {
201
+ name: string;
202
+ version: string;
203
+ };
204
+ /** Operating system */
205
+ os: {
206
+ name: string;
207
+ version: string;
208
+ };
209
+ /** Device type */
210
+ deviceType: 'desktop' | 'tablet' | 'mobile';
211
+ /** Screen resolution */
212
+ screenResolution: {
213
+ width: number;
214
+ height: number;
215
+ };
216
+ /** Pixel ratio */
217
+ pixelRatio: number;
218
+ /** Language/locale */
219
+ language: string;
220
+ /** Timezone */
221
+ timezone: string;
222
+ /** Referrer */
223
+ referrer?: string;
224
+ }
225
+ export interface ErrorInfo {
226
+ message: string;
227
+ stack?: string;
228
+ type: string;
229
+ filename?: string;
230
+ lineno?: number;
231
+ colno?: number;
232
+ timestamp: string;
233
+ context?: PageContext;
234
+ }
235
+ export interface SubmitResult {
236
+ success: boolean;
237
+ feedbackId?: string;
238
+ shortId?: string;
239
+ screenshotUrl?: string;
240
+ videoUrl?: string;
241
+ message?: string;
242
+ error?: string;
243
+ }
244
+ export interface APIResponse<T = any> {
245
+ success: boolean;
246
+ data?: T;
247
+ error?: string;
248
+ statusCode?: number;
249
+ }
250
+ export interface WidgetConfig {
251
+ position: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
252
+ buttonText: string;
253
+ buttonIcon?: string;
254
+ primaryColor?: string;
255
+ textColor?: string;
256
+ zIndex?: number;
257
+ }
258
+ export interface WidgetState {
259
+ isOpen: boolean;
260
+ isMinimized: boolean;
261
+ isCapturing: boolean;
262
+ isSubmitting: boolean;
263
+ captureResult?: CaptureResult;
264
+ error?: string;
265
+ }
266
+ export interface Translations {
267
+ feedbackButton: string;
268
+ titleLabel: string;
269
+ titlePlaceholder: string;
270
+ descriptionLabel: string;
271
+ descriptionPlaceholder: string;
272
+ typeLabel: string;
273
+ priorityLabel: string;
274
+ typeBug: string;
275
+ typeFeature: string;
276
+ typeImprovement: string;
277
+ typeQuestion: string;
278
+ typeOther: string;
279
+ priorityLow: string;
280
+ priorityMedium: string;
281
+ priorityHigh: string;
282
+ priorityCritical: string;
283
+ submitButton: string;
284
+ cancelButton: string;
285
+ captureButton: string;
286
+ retakeButton: string;
287
+ submitting: string;
288
+ submitSuccess: string;
289
+ submitError: string;
290
+ captureSuccess: string;
291
+ captureError: string;
292
+ screenshotLabel: string;
293
+ includeScreenshot: string;
294
+ annotateScreenshot: string;
295
+ includeConsole: string;
296
+ includeNetwork: string;
297
+ }
298
+ export declare const DEFAULT_TRANSLATIONS: Translations;
299
+ export declare const TRANSLATIONS: Record<string, Translations>;
@@ -0,0 +1,55 @@
1
+ /**
2
+ * CheckFlow Vue 3 Integration
3
+ * Provides Vue composables, plugin, and components
4
+ */
5
+ import { App, InjectionKey, Ref } from 'vue';
6
+ import { CheckFlow } from '../checkflow';
7
+ import { CheckFlowOptions, FeedbackData, CaptureResult, SubmitResult, UserInfo, FeedbackType, FeedbackPriority } from '../types';
8
+ export declare const CheckFlowKey: InjectionKey<CheckFlowInstance>;
9
+ interface CheckFlowInstance {
10
+ checkflow: Ref<CheckFlow | null>;
11
+ isReady: Ref<boolean>;
12
+ capture: () => Promise<CaptureResult | null>;
13
+ submitFeedback: (feedback: FeedbackData) => Promise<SubmitResult>;
14
+ openWidget: () => void;
15
+ closeWidget: () => void;
16
+ setUser: (user: UserInfo) => void;
17
+ clearUser: () => void;
18
+ }
19
+ export interface CheckFlowPluginOptions extends CheckFlowOptions {
20
+ apiKey: string;
21
+ }
22
+ export declare const CheckFlowPlugin: {
23
+ install(app: App, options: CheckFlowPluginOptions): void;
24
+ };
25
+ export declare function useCheckFlow(): CheckFlowInstance;
26
+ export declare function provideCheckFlow(apiKey: string, options?: CheckFlowOptions): CheckFlowInstance;
27
+ interface UseFeedbackFormOptions {
28
+ onSuccess?: (result: SubmitResult) => void;
29
+ onError?: (error: Error) => void;
30
+ defaultType?: FeedbackType;
31
+ defaultPriority?: FeedbackPriority;
32
+ }
33
+ export declare function useFeedbackForm(options?: UseFeedbackFormOptions): {
34
+ formState: {
35
+ title: string;
36
+ description: string;
37
+ type: FeedbackType;
38
+ priority: FeedbackPriority;
39
+ includeScreenshot: boolean;
40
+ includeConsoleLogs: boolean;
41
+ includeNetworkLogs: boolean;
42
+ };
43
+ screenshot: Ref<string | null, string | null>;
44
+ captureScreenshot: () => Promise<CaptureResult | null>;
45
+ submit: () => Promise<SubmitResult | null>;
46
+ reset: () => void;
47
+ isSubmitting: Ref<boolean, boolean>;
48
+ isValid: import("vue").ComputedRef<boolean>;
49
+ error: Ref<string | null, string | null>;
50
+ };
51
+ export declare function useErrorHandler(): {
52
+ captureException: (error: Error, context?: Record<string, any>) => void;
53
+ handleError: (error: unknown) => void;
54
+ };
55
+ export type { CheckFlowOptions, FeedbackData, CaptureResult, SubmitResult, UserInfo, FeedbackType, FeedbackPriority, };
@@ -0,0 +1,98 @@
1
+ /**
2
+ * CheckFlow Feedback Widget
3
+ * Pure JavaScript widget that works without frameworks
4
+ */
5
+ import { FeedbackType, FeedbackPriority, CaptureResult, Translations } from '../types';
6
+ import { ContextCapture } from '../context-capture';
7
+ import type { Annotation } from '../annotation';
8
+ declare global {
9
+ interface ImageCapture {
10
+ grabFrame(): Promise<ImageBitmap>;
11
+ takePhoto(): Promise<Blob>;
12
+ }
13
+ var ImageCapture: {
14
+ prototype: ImageCapture;
15
+ new (track: MediaStreamTrack): ImageCapture;
16
+ };
17
+ }
18
+ import './styles.css';
19
+ export interface WidgetOptions {
20
+ position?: 'bottom-right' | 'bottom-left' | 'top-right' | 'top-left';
21
+ buttonText?: string;
22
+ primaryColor?: string;
23
+ zIndex?: number;
24
+ locale?: string;
25
+ translations?: Partial<Translations>;
26
+ onSubmit?: (data: WidgetSubmitData) => Promise<void>;
27
+ onCapture?: () => Promise<CaptureResult>;
28
+ onClose?: () => void;
29
+ }
30
+ export interface WidgetSubmitData {
31
+ name: string;
32
+ email: string;
33
+ description: string;
34
+ type: FeedbackType;
35
+ priority: FeedbackPriority;
36
+ screenshot?: string;
37
+ annotations?: Annotation[];
38
+ includeConsole: boolean;
39
+ includeNetwork: boolean;
40
+ }
41
+ export declare class FeedbackWidget {
42
+ private container;
43
+ private options;
44
+ private translations;
45
+ private state;
46
+ private capture;
47
+ private annotationEditor;
48
+ private currentAnnotations;
49
+ constructor(options?: WidgetOptions);
50
+ /**
51
+ * Mount the widget to the DOM
52
+ */
53
+ mount(): void;
54
+ /**
55
+ * Unmount the widget
56
+ */
57
+ unmount(): void;
58
+ /**
59
+ * Open the feedback modal
60
+ */
61
+ open(): void;
62
+ /**
63
+ * Close the feedback modal
64
+ */
65
+ close(): void;
66
+ private renderTrigger;
67
+ /**
68
+ * Calculate contrast color (white or black) based on background color
69
+ */
70
+ private getContrastColor;
71
+ private renderModal;
72
+ private renderExpandedModal;
73
+ private renderTypeOptions;
74
+ private renderCaptureButton;
75
+ private renderScreenshotPreview;
76
+ private renderSuccess;
77
+ private render;
78
+ private bindEvents;
79
+ private captureScreenshot;
80
+ /**
81
+ * Capture screen using native browser API (getDisplayMedia)
82
+ * Optimized for instant capture after user allows
83
+ */
84
+ private captureWithDisplayMedia;
85
+ /**
86
+ * Open the annotation editor for the current screenshot
87
+ */
88
+ private openAnnotationEditor;
89
+ private handleSubmit;
90
+ /**
91
+ * Update widget options
92
+ */
93
+ setOptions(options: Partial<WidgetOptions>): void;
94
+ /**
95
+ * Get capture context
96
+ */
97
+ getCapture(): ContextCapture;
98
+ }
@@ -0,0 +1,2 @@
1
+ export { FeedbackWidget } from './Widget';
2
+ export type { WidgetOptions, WidgetSubmitData } from './Widget';
package/package.json ADDED
@@ -0,0 +1,69 @@
1
+ {
2
+ "name": "@checkflow/sdk",
3
+ "version": "1.0.1",
4
+ "type": "module",
5
+ "description": "CheckFlow SDK for capturing user feedback with context",
6
+ "main": "dist/index.js",
7
+ "module": "dist/index.esm.js",
8
+ "types": "dist/index.d.ts",
9
+ "files": [
10
+ "dist",
11
+ "README.md"
12
+ ],
13
+ "scripts": {
14
+ "build": "rollup -c rollup.config.mjs",
15
+ "build:watch": "rollup -c -w",
16
+ "test": "jest",
17
+ "lint": "eslint src --ext .ts,.tsx",
18
+ "prepublishOnly": "npm run build"
19
+ },
20
+ "keywords": [
21
+ "feedback",
22
+ "bug-report",
23
+ "screenshot",
24
+ "context-capture",
25
+ "error-tracking",
26
+ "user-feedback"
27
+ ],
28
+ "author": "checkFlow",
29
+ "license": "MIT",
30
+ "repository": {
31
+ "type": "git",
32
+ "url": "git+https://github.com/checkflow/checkflow-sdk.git"
33
+ },
34
+ "devDependencies": {
35
+ "@rollup/plugin-commonjs": "^25.0.7",
36
+ "@rollup/plugin-node-resolve": "^15.2.3",
37
+ "@rollup/plugin-typescript": "^11.1.5",
38
+ "@types/jest": "^29.5.11",
39
+ "@types/node": "^20.10.5",
40
+ "@types/react": "^18.3.27",
41
+ "@types/react-dom": "^18.3.7",
42
+ "@typescript-eslint/eslint-plugin": "^6.15.0",
43
+ "@typescript-eslint/parser": "^6.15.0",
44
+ "eslint": "^8.56.0",
45
+ "jest": "^29.7.0",
46
+ "rollup": "^4.9.1",
47
+ "rollup-plugin-dts": "^6.1.0",
48
+ "rollup-plugin-postcss": "^4.0.2",
49
+ "ts-jest": "^29.1.1",
50
+ "tslib": "^2.6.2",
51
+ "typescript": "^5.3.3",
52
+ "vue": "^3.5.25"
53
+ },
54
+ "dependencies": {
55
+ "html2canvas": "^1.4.1"
56
+ },
57
+ "peerDependencies": {
58
+ "react": ">=16.8.0",
59
+ "vue": ">=3.0.0"
60
+ },
61
+ "peerDependenciesMeta": {
62
+ "react": {
63
+ "optional": true
64
+ },
65
+ "vue": {
66
+ "optional": true
67
+ }
68
+ }
69
+ }