@jarve/bug-reporter 0.4.3 → 1.0.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/README.md +3 -0
- package/dist/index.d.mts +134 -14
- package/dist/index.d.ts +134 -14
- package/dist/index.js +636 -369
- package/dist/index.mjs +623 -358
- package/dist/styles.css +2 -0
- package/package.json +23 -9
- package/dist/index.js.map +0 -1
- package/dist/index.mjs.map +0 -1
package/README.md
CHANGED
|
@@ -19,6 +19,7 @@ Go to your JARVE Agency dashboard at `/admin/bug-reports/sites` and:
|
|
|
19
19
|
- Enter your site name and color
|
|
20
20
|
- Click **Generate API Key**
|
|
21
21
|
- Copy the API key (starts with `brk_`)
|
|
22
|
+
- Copy the public Site ID for the same site
|
|
22
23
|
|
|
23
24
|
### 2. Install
|
|
24
25
|
|
|
@@ -57,6 +58,7 @@ export default function RootLayout({ children }: { children: React.ReactNode })
|
|
|
57
58
|
<JarveBugReporter
|
|
58
59
|
apiUrl="https://www.jarve.com.au/api/bug-reporter/external"
|
|
59
60
|
apiKey="brk_your_api_key_here"
|
|
61
|
+
siteId="your_public_site_id"
|
|
60
62
|
user={{ name: 'James', email: 'james@example.com' }}
|
|
61
63
|
>
|
|
62
64
|
{children}
|
|
@@ -77,6 +79,7 @@ Click the blue bug icon (bottom-right) to report bugs. They'll appear in your JA
|
|
|
77
79
|
| ---------------- | --------------------------------- | -------- | -------------------------------------------------------------------------------------- |
|
|
78
80
|
| `apiUrl` | `string` | Yes | Base URL for the external bug reporter API |
|
|
79
81
|
| `apiKey` | `string` | Yes | Your site's API key (starts with `brk_`) |
|
|
82
|
+
| `siteId` | `string` | Yes | Public site identifier used for widget state and labels. Do not derive it from apiKey. |
|
|
80
83
|
| `buttonPosition` | `'left' \| 'right'` | No | Floating button position. Default: `'right'`. Sibling-aware with other @jarve widgets. |
|
|
81
84
|
| `user` | `{ name: string, email: string }` | No | User info. If omitted, the AI will ask during conversation |
|
|
82
85
|
| `children` | `ReactNode` | Yes | Your app content |
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { JarveTheme } from '@jarve/widget-shared';
|
|
2
3
|
|
|
3
4
|
type FloatingButtonPosition = 'left' | 'right';
|
|
4
5
|
|
|
@@ -6,35 +7,154 @@ interface BugReporterUser {
|
|
|
6
7
|
name: string;
|
|
7
8
|
email: string;
|
|
8
9
|
}
|
|
10
|
+
interface ClickedElement {
|
|
11
|
+
tagName: string;
|
|
12
|
+
textContent: string | null;
|
|
13
|
+
className: string;
|
|
14
|
+
id: string | null;
|
|
15
|
+
ariaLabel: string | null;
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
selectorPath: string;
|
|
18
|
+
clickX: number;
|
|
19
|
+
clickY: number;
|
|
20
|
+
relativeClickX: number;
|
|
21
|
+
relativeClickY: number;
|
|
22
|
+
}
|
|
23
|
+
interface CaptureMetadata {
|
|
24
|
+
pageUrl: string;
|
|
25
|
+
sectionId: string | null;
|
|
26
|
+
viewportWidth: number;
|
|
27
|
+
viewportHeight: number;
|
|
28
|
+
deviceType: 'desktop' | 'tablet' | 'mobile';
|
|
29
|
+
browser: string;
|
|
30
|
+
os: string;
|
|
31
|
+
timestamp: string;
|
|
32
|
+
timestampUtc: string;
|
|
33
|
+
reporterName: string;
|
|
34
|
+
reporterEmail: string;
|
|
35
|
+
/**
|
|
36
|
+
* Public site identifier supplied explicitly by the host app. This is used
|
|
37
|
+
* for prompt context and client-side draft scoping; it must never be
|
|
38
|
+
* derived from the secret API key.
|
|
39
|
+
*/
|
|
40
|
+
siteId: string;
|
|
41
|
+
screenshotCaptureFailed?: boolean;
|
|
42
|
+
clickedElement?: ClickedElement;
|
|
43
|
+
}
|
|
44
|
+
interface ConversationMessage {
|
|
45
|
+
role: 'user' | 'assistant';
|
|
46
|
+
content: string;
|
|
47
|
+
}
|
|
48
|
+
interface ConsoleError {
|
|
49
|
+
message: string;
|
|
50
|
+
source?: string;
|
|
51
|
+
lineno?: number;
|
|
52
|
+
colno?: number;
|
|
53
|
+
timestamp: string;
|
|
54
|
+
}
|
|
55
|
+
interface FailedNetworkRequest {
|
|
56
|
+
url: string;
|
|
57
|
+
hasQueryString: boolean;
|
|
58
|
+
method: string;
|
|
59
|
+
status: number;
|
|
60
|
+
statusText: string;
|
|
61
|
+
/**
|
|
62
|
+
* Response body text, truncated to `TRUNCATE_LEN`. Always `null` unless
|
|
63
|
+
* the consumer opted in via `captureResponseBodies`. See Issue B4 —
|
|
64
|
+
* bodies routinely contain JWTs, Supabase RLS errors, and Stripe IDs,
|
|
65
|
+
* so we capture only status metadata by default.
|
|
66
|
+
*/
|
|
67
|
+
responseBody: string | null;
|
|
68
|
+
/**
|
|
69
|
+
* The response `Content-Type` header, captured for every failed request
|
|
70
|
+
* regardless of the body-capture opt-in. Useful for triage without the
|
|
71
|
+
* privacy cost of the full body.
|
|
72
|
+
*/
|
|
73
|
+
contentType: string | null;
|
|
74
|
+
timestamp: string;
|
|
75
|
+
}
|
|
76
|
+
interface CaptureResult {
|
|
77
|
+
screenshot: Blob;
|
|
78
|
+
metadata: CaptureMetadata;
|
|
79
|
+
consoleErrors: ConsoleError[];
|
|
80
|
+
networkErrors: FailedNetworkRequest[];
|
|
81
|
+
}
|
|
9
82
|
interface BugReporterApiConfig {
|
|
10
83
|
apiUrl: string;
|
|
11
84
|
apiKey: string;
|
|
12
85
|
}
|
|
13
86
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Payload handed to `onBeforeSubmit` immediately before the widget POSTs
|
|
89
|
+
* `/submit`. Consumers can mutate/redact in place and return either the
|
|
90
|
+
* same reference or a freshly built object — whatever is returned replaces
|
|
91
|
+
* the payload wholesale. See Issue B8.
|
|
92
|
+
*/
|
|
93
|
+
interface BugReportSubmitPayload {
|
|
94
|
+
metadata: CaptureResult['metadata'];
|
|
95
|
+
conversation: ConversationMessage[];
|
|
96
|
+
structuredReport: {
|
|
97
|
+
summary: string;
|
|
98
|
+
expected_behavior: string;
|
|
99
|
+
actual_behavior: string;
|
|
100
|
+
reproducibility: string;
|
|
101
|
+
specific_data: string;
|
|
102
|
+
severity: string;
|
|
103
|
+
} | undefined;
|
|
104
|
+
consoleErrors: CaptureResult['consoleErrors'];
|
|
105
|
+
networkErrors: CaptureResult['networkErrors'];
|
|
106
|
+
clickedElement: CaptureResult['metadata']['clickedElement'] | null;
|
|
26
107
|
}
|
|
108
|
+
|
|
27
109
|
interface JarveBugReporterProps {
|
|
28
110
|
/** Base URL for the external bug reporter API (e.g. "https://www.jarve.com.au/api/bug-reporter/external") */
|
|
29
111
|
apiUrl: string;
|
|
30
112
|
/** API key for your site (starts with "brk_") */
|
|
31
113
|
apiKey: string;
|
|
114
|
+
/**
|
|
115
|
+
* Public site identifier for this widget install. Used for client-side draft
|
|
116
|
+
* scoping and prompt context. Must be supplied explicitly by the host app
|
|
117
|
+
* and must never be derived from the secret API key.
|
|
118
|
+
*/
|
|
119
|
+
siteId: string;
|
|
32
120
|
/** Optional position for the floating button (default: 'right') */
|
|
33
121
|
buttonPosition?: FloatingButtonPosition;
|
|
34
122
|
/** Optional user info. If not provided, the AI will ask for name/email during the conversation. */
|
|
35
123
|
user?: BugReporterUser;
|
|
124
|
+
/**
|
|
125
|
+
* Base z-index for every rendered widget layer (FAB, overlay, modal).
|
|
126
|
+
* Default `10000`. Raise this when the host application already uses high
|
|
127
|
+
* z-indexes for its own modals/toasts and the widget needs to sit above
|
|
128
|
+
* them. See Issue F2.
|
|
129
|
+
*/
|
|
130
|
+
zIndexBase?: number;
|
|
131
|
+
/**
|
|
132
|
+
* When `true`, capture a truncated copy of each failed response body in
|
|
133
|
+
* addition to status metadata. Default `false`. Response bodies routinely
|
|
134
|
+
* contain JWTs, Supabase RLS errors exposing schema, and vendor IDs —
|
|
135
|
+
* only opt in when you have reviewed those privacy implications. See
|
|
136
|
+
* Issue B4.
|
|
137
|
+
*/
|
|
138
|
+
captureResponseBodies?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Color theme for the bug-report modal. Defaults to `'auto'` which
|
|
141
|
+
* follows `matchMedia('(prefers-color-scheme: dark)')`. Use `'light'` or
|
|
142
|
+
* `'dark'` to force a palette. The widget owns its own `.dark` class —
|
|
143
|
+
* consumer apps do not need `darkMode: 'class'` in their Tailwind config.
|
|
144
|
+
* See Issue E11.
|
|
145
|
+
*/
|
|
146
|
+
theme?: JarveTheme;
|
|
147
|
+
/**
|
|
148
|
+
* Final chance to scrub the bug-report payload before it leaves the
|
|
149
|
+
* browser. The hook receives the full `/submit` payload and must return
|
|
150
|
+
* either a replacement object (mutated or rebuilt) or `null`/`false` /
|
|
151
|
+
* throw to cancel the submit. On cancel the modal stays open with the
|
|
152
|
+
* draft intact and shows an inline `role="alert"` error so the user can
|
|
153
|
+
* retry. Async hooks are awaited. See Issue B8.
|
|
154
|
+
*/
|
|
155
|
+
onBeforeSubmit?: (payload: BugReportSubmitPayload) => BugReportSubmitPayload | null | false | Promise<BugReportSubmitPayload | null | false>;
|
|
36
156
|
children: React.ReactNode;
|
|
37
157
|
}
|
|
38
|
-
declare function JarveBugReporter({ apiUrl, apiKey, user, buttonPosition, children, }: JarveBugReporterProps): react_jsx_runtime.JSX.Element;
|
|
158
|
+
declare function JarveBugReporter({ apiUrl, apiKey, siteId, user, buttonPosition, zIndexBase, captureResponseBodies, theme, onBeforeSubmit, children, }: JarveBugReporterProps): react_jsx_runtime.JSX.Element;
|
|
39
159
|
|
|
40
|
-
export { type BugReporterApiConfig, type BugReporterUser, type FloatingButtonPosition, JarveBugReporter };
|
|
160
|
+
export { type BugReportSubmitPayload, type BugReporterApiConfig, type BugReporterUser, type FloatingButtonPosition, JarveBugReporter, type JarveBugReporterProps };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import { JarveTheme } from '@jarve/widget-shared';
|
|
2
3
|
|
|
3
4
|
type FloatingButtonPosition = 'left' | 'right';
|
|
4
5
|
|
|
@@ -6,35 +7,154 @@ interface BugReporterUser {
|
|
|
6
7
|
name: string;
|
|
7
8
|
email: string;
|
|
8
9
|
}
|
|
10
|
+
interface ClickedElement {
|
|
11
|
+
tagName: string;
|
|
12
|
+
textContent: string | null;
|
|
13
|
+
className: string;
|
|
14
|
+
id: string | null;
|
|
15
|
+
ariaLabel: string | null;
|
|
16
|
+
dataAttributes: Record<string, string>;
|
|
17
|
+
selectorPath: string;
|
|
18
|
+
clickX: number;
|
|
19
|
+
clickY: number;
|
|
20
|
+
relativeClickX: number;
|
|
21
|
+
relativeClickY: number;
|
|
22
|
+
}
|
|
23
|
+
interface CaptureMetadata {
|
|
24
|
+
pageUrl: string;
|
|
25
|
+
sectionId: string | null;
|
|
26
|
+
viewportWidth: number;
|
|
27
|
+
viewportHeight: number;
|
|
28
|
+
deviceType: 'desktop' | 'tablet' | 'mobile';
|
|
29
|
+
browser: string;
|
|
30
|
+
os: string;
|
|
31
|
+
timestamp: string;
|
|
32
|
+
timestampUtc: string;
|
|
33
|
+
reporterName: string;
|
|
34
|
+
reporterEmail: string;
|
|
35
|
+
/**
|
|
36
|
+
* Public site identifier supplied explicitly by the host app. This is used
|
|
37
|
+
* for prompt context and client-side draft scoping; it must never be
|
|
38
|
+
* derived from the secret API key.
|
|
39
|
+
*/
|
|
40
|
+
siteId: string;
|
|
41
|
+
screenshotCaptureFailed?: boolean;
|
|
42
|
+
clickedElement?: ClickedElement;
|
|
43
|
+
}
|
|
44
|
+
interface ConversationMessage {
|
|
45
|
+
role: 'user' | 'assistant';
|
|
46
|
+
content: string;
|
|
47
|
+
}
|
|
48
|
+
interface ConsoleError {
|
|
49
|
+
message: string;
|
|
50
|
+
source?: string;
|
|
51
|
+
lineno?: number;
|
|
52
|
+
colno?: number;
|
|
53
|
+
timestamp: string;
|
|
54
|
+
}
|
|
55
|
+
interface FailedNetworkRequest {
|
|
56
|
+
url: string;
|
|
57
|
+
hasQueryString: boolean;
|
|
58
|
+
method: string;
|
|
59
|
+
status: number;
|
|
60
|
+
statusText: string;
|
|
61
|
+
/**
|
|
62
|
+
* Response body text, truncated to `TRUNCATE_LEN`. Always `null` unless
|
|
63
|
+
* the consumer opted in via `captureResponseBodies`. See Issue B4 —
|
|
64
|
+
* bodies routinely contain JWTs, Supabase RLS errors, and Stripe IDs,
|
|
65
|
+
* so we capture only status metadata by default.
|
|
66
|
+
*/
|
|
67
|
+
responseBody: string | null;
|
|
68
|
+
/**
|
|
69
|
+
* The response `Content-Type` header, captured for every failed request
|
|
70
|
+
* regardless of the body-capture opt-in. Useful for triage without the
|
|
71
|
+
* privacy cost of the full body.
|
|
72
|
+
*/
|
|
73
|
+
contentType: string | null;
|
|
74
|
+
timestamp: string;
|
|
75
|
+
}
|
|
76
|
+
interface CaptureResult {
|
|
77
|
+
screenshot: Blob;
|
|
78
|
+
metadata: CaptureMetadata;
|
|
79
|
+
consoleErrors: ConsoleError[];
|
|
80
|
+
networkErrors: FailedNetworkRequest[];
|
|
81
|
+
}
|
|
9
82
|
interface BugReporterApiConfig {
|
|
10
83
|
apiUrl: string;
|
|
11
84
|
apiKey: string;
|
|
12
85
|
}
|
|
13
86
|
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
87
|
+
/**
|
|
88
|
+
* Payload handed to `onBeforeSubmit` immediately before the widget POSTs
|
|
89
|
+
* `/submit`. Consumers can mutate/redact in place and return either the
|
|
90
|
+
* same reference or a freshly built object — whatever is returned replaces
|
|
91
|
+
* the payload wholesale. See Issue B8.
|
|
92
|
+
*/
|
|
93
|
+
interface BugReportSubmitPayload {
|
|
94
|
+
metadata: CaptureResult['metadata'];
|
|
95
|
+
conversation: ConversationMessage[];
|
|
96
|
+
structuredReport: {
|
|
97
|
+
summary: string;
|
|
98
|
+
expected_behavior: string;
|
|
99
|
+
actual_behavior: string;
|
|
100
|
+
reproducibility: string;
|
|
101
|
+
specific_data: string;
|
|
102
|
+
severity: string;
|
|
103
|
+
} | undefined;
|
|
104
|
+
consoleErrors: CaptureResult['consoleErrors'];
|
|
105
|
+
networkErrors: CaptureResult['networkErrors'];
|
|
106
|
+
clickedElement: CaptureResult['metadata']['clickedElement'] | null;
|
|
26
107
|
}
|
|
108
|
+
|
|
27
109
|
interface JarveBugReporterProps {
|
|
28
110
|
/** Base URL for the external bug reporter API (e.g. "https://www.jarve.com.au/api/bug-reporter/external") */
|
|
29
111
|
apiUrl: string;
|
|
30
112
|
/** API key for your site (starts with "brk_") */
|
|
31
113
|
apiKey: string;
|
|
114
|
+
/**
|
|
115
|
+
* Public site identifier for this widget install. Used for client-side draft
|
|
116
|
+
* scoping and prompt context. Must be supplied explicitly by the host app
|
|
117
|
+
* and must never be derived from the secret API key.
|
|
118
|
+
*/
|
|
119
|
+
siteId: string;
|
|
32
120
|
/** Optional position for the floating button (default: 'right') */
|
|
33
121
|
buttonPosition?: FloatingButtonPosition;
|
|
34
122
|
/** Optional user info. If not provided, the AI will ask for name/email during the conversation. */
|
|
35
123
|
user?: BugReporterUser;
|
|
124
|
+
/**
|
|
125
|
+
* Base z-index for every rendered widget layer (FAB, overlay, modal).
|
|
126
|
+
* Default `10000`. Raise this when the host application already uses high
|
|
127
|
+
* z-indexes for its own modals/toasts and the widget needs to sit above
|
|
128
|
+
* them. See Issue F2.
|
|
129
|
+
*/
|
|
130
|
+
zIndexBase?: number;
|
|
131
|
+
/**
|
|
132
|
+
* When `true`, capture a truncated copy of each failed response body in
|
|
133
|
+
* addition to status metadata. Default `false`. Response bodies routinely
|
|
134
|
+
* contain JWTs, Supabase RLS errors exposing schema, and vendor IDs —
|
|
135
|
+
* only opt in when you have reviewed those privacy implications. See
|
|
136
|
+
* Issue B4.
|
|
137
|
+
*/
|
|
138
|
+
captureResponseBodies?: boolean;
|
|
139
|
+
/**
|
|
140
|
+
* Color theme for the bug-report modal. Defaults to `'auto'` which
|
|
141
|
+
* follows `matchMedia('(prefers-color-scheme: dark)')`. Use `'light'` or
|
|
142
|
+
* `'dark'` to force a palette. The widget owns its own `.dark` class —
|
|
143
|
+
* consumer apps do not need `darkMode: 'class'` in their Tailwind config.
|
|
144
|
+
* See Issue E11.
|
|
145
|
+
*/
|
|
146
|
+
theme?: JarveTheme;
|
|
147
|
+
/**
|
|
148
|
+
* Final chance to scrub the bug-report payload before it leaves the
|
|
149
|
+
* browser. The hook receives the full `/submit` payload and must return
|
|
150
|
+
* either a replacement object (mutated or rebuilt) or `null`/`false` /
|
|
151
|
+
* throw to cancel the submit. On cancel the modal stays open with the
|
|
152
|
+
* draft intact and shows an inline `role="alert"` error so the user can
|
|
153
|
+
* retry. Async hooks are awaited. See Issue B8.
|
|
154
|
+
*/
|
|
155
|
+
onBeforeSubmit?: (payload: BugReportSubmitPayload) => BugReportSubmitPayload | null | false | Promise<BugReportSubmitPayload | null | false>;
|
|
36
156
|
children: React.ReactNode;
|
|
37
157
|
}
|
|
38
|
-
declare function JarveBugReporter({ apiUrl, apiKey, user, buttonPosition, children, }: JarveBugReporterProps): react_jsx_runtime.JSX.Element;
|
|
158
|
+
declare function JarveBugReporter({ apiUrl, apiKey, siteId, user, buttonPosition, zIndexBase, captureResponseBodies, theme, onBeforeSubmit, children, }: JarveBugReporterProps): react_jsx_runtime.JSX.Element;
|
|
39
159
|
|
|
40
|
-
export { type BugReporterApiConfig, type BugReporterUser, type FloatingButtonPosition, JarveBugReporter };
|
|
160
|
+
export { type BugReportSubmitPayload, type BugReporterApiConfig, type BugReporterUser, type FloatingButtonPosition, JarveBugReporter, type JarveBugReporterProps };
|