@diegotsi/flint-react 1.0.1 → 1.2.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/dist/index.cjs +66 -41
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +5 -120
- package/dist/index.d.ts +5 -120
- package/dist/index.js +57 -33
- package/dist/index.js.map +1 -1
- package/package.json +3 -2
package/dist/index.d.ts
CHANGED
|
@@ -1,122 +1,6 @@
|
|
|
1
|
+
import { FlintUser, Theme, EnvironmentInfo, ConsoleEntry, NetworkEntry, FormErrorEntry, ReportPayload, ReportResult, FlintWidgetProps } from '@diegotsi/flint-core';
|
|
2
|
+
export { Flint, FlintConfig, FlintUser, FlintWidgetProps, Locale, ReportPayload, ReportResult, Severity, Theme, ThemeOverride, flint } from '@diegotsi/flint-core';
|
|
1
3
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
export { flint } from '@flint/core';
|
|
3
|
-
|
|
4
|
-
type Severity = "P1" | "P2" | "P3" | "P4";
|
|
5
|
-
interface EnvironmentInfo {
|
|
6
|
-
browser: string;
|
|
7
|
-
os: string;
|
|
8
|
-
viewport: string;
|
|
9
|
-
screen: string;
|
|
10
|
-
language: string;
|
|
11
|
-
timezone: string;
|
|
12
|
-
online: boolean;
|
|
13
|
-
}
|
|
14
|
-
interface ConsoleEntry {
|
|
15
|
-
level: "log" | "warn" | "error";
|
|
16
|
-
args: string;
|
|
17
|
-
timestamp: number;
|
|
18
|
-
}
|
|
19
|
-
interface NetworkEntry {
|
|
20
|
-
method: string;
|
|
21
|
-
url: string;
|
|
22
|
-
status: number;
|
|
23
|
-
duration: number;
|
|
24
|
-
timestamp: number;
|
|
25
|
-
}
|
|
26
|
-
type Locale = "pt-BR" | "en-US";
|
|
27
|
-
type Theme = "light" | "dark" | ThemeOverride;
|
|
28
|
-
interface ThemeOverride {
|
|
29
|
-
background?: string;
|
|
30
|
-
accent?: string;
|
|
31
|
-
text?: string;
|
|
32
|
-
border?: string;
|
|
33
|
-
}
|
|
34
|
-
interface FlintUser {
|
|
35
|
-
id: string;
|
|
36
|
-
name: string;
|
|
37
|
-
email?: string;
|
|
38
|
-
}
|
|
39
|
-
interface FlintExtraFields {
|
|
40
|
-
/** Session replay URL from Datadog RUM, FullStory, LogRocket, etc. Pass a function for lazy evaluation. */
|
|
41
|
-
sessionReplay?: string | (() => string);
|
|
42
|
-
[key: string]: unknown;
|
|
43
|
-
}
|
|
44
|
-
interface FlintWidgetProps {
|
|
45
|
-
/** Project API key — get this from the flint-server admin API */
|
|
46
|
-
projectKey: string;
|
|
47
|
-
/** Full URL of the flint-server, e.g. "https://bugs.example.com" */
|
|
48
|
-
serverUrl: string;
|
|
49
|
-
/** Authenticated user info (optional) */
|
|
50
|
-
user?: FlintUser;
|
|
51
|
-
/** Arbitrary metadata to attach to every report */
|
|
52
|
-
meta?: Record<string, unknown>;
|
|
53
|
-
/** Extra fields for developer use (e.g. external session replay URL) */
|
|
54
|
-
extraFields?: FlintExtraFields;
|
|
55
|
-
/** Label shown on the trigger button. Default: "Reportar bug" */
|
|
56
|
-
buttonLabel?: string;
|
|
57
|
-
/** Locale for UI strings. Default: "pt-BR" */
|
|
58
|
-
locale?: Locale;
|
|
59
|
-
/** Visual theme. Default: "light" */
|
|
60
|
-
theme?: Theme;
|
|
61
|
-
/** Custom z-index for the widget. Default: 9999 */
|
|
62
|
-
zIndex?: number;
|
|
63
|
-
/** URL of the admin/status page for reporters to track their bugs */
|
|
64
|
-
statusPageUrl?: string;
|
|
65
|
-
/**
|
|
66
|
-
* Datadog site hostname for auto-generating RUM Session Replay deep links.
|
|
67
|
-
* When set, the widget auto-detects `window.DD_RUM` and generates a direct
|
|
68
|
-
* link to the session replay at the exact moment the bug was reported.
|
|
69
|
-
* Examples: "app.datadoghq.com", "app.datadoghq.eu", "app.us5.datadoghq.com"
|
|
70
|
-
*/
|
|
71
|
-
datadogSite?: string;
|
|
72
|
-
/** Enable session replay recording. Default: true */
|
|
73
|
-
enableReplay?: boolean;
|
|
74
|
-
/** Enable screenshot capture. Default: true */
|
|
75
|
-
enableScreenshot?: boolean;
|
|
76
|
-
/** Enable console log collection. Default: true */
|
|
77
|
-
enableConsole?: boolean;
|
|
78
|
-
/** Enable network error collection. Default: true */
|
|
79
|
-
enableNetwork?: boolean;
|
|
80
|
-
/** Enable frustration detection (rage clicks, dead clicks, error loops). Default: false */
|
|
81
|
-
enableFrustration?: boolean;
|
|
82
|
-
/** Auto-submit bug report on frustration detection. Default: false */
|
|
83
|
-
autoReportFrustration?: boolean;
|
|
84
|
-
/** Called before report submission. Return false to cancel. */
|
|
85
|
-
onBeforeSubmit?: (payload: ReportPayload) => boolean | Promise<boolean>;
|
|
86
|
-
/** Called after successful submission */
|
|
87
|
-
onSuccess?: (result: ReportResult) => void;
|
|
88
|
-
/** Called when submission fails */
|
|
89
|
-
onError?: (error: Error) => void;
|
|
90
|
-
/** Called when the modal opens */
|
|
91
|
-
onOpen?: () => void;
|
|
92
|
-
/** Called when the modal closes */
|
|
93
|
-
onClose?: () => void;
|
|
94
|
-
}
|
|
95
|
-
interface ReportPayload {
|
|
96
|
-
reporterId: string;
|
|
97
|
-
reporterName: string;
|
|
98
|
-
reporterEmail?: string;
|
|
99
|
-
description: string;
|
|
100
|
-
expectedBehavior?: string;
|
|
101
|
-
stepsToReproduce?: {
|
|
102
|
-
action: string;
|
|
103
|
-
result: string;
|
|
104
|
-
}[];
|
|
105
|
-
externalReplayUrl?: string;
|
|
106
|
-
additionalContext?: string;
|
|
107
|
-
severity: Severity;
|
|
108
|
-
url?: string;
|
|
109
|
-
meta?: Record<string, unknown>;
|
|
110
|
-
label?: string;
|
|
111
|
-
}
|
|
112
|
-
interface ReportResult {
|
|
113
|
-
id: string;
|
|
114
|
-
status: string;
|
|
115
|
-
githubIssueUrl?: string | null;
|
|
116
|
-
slackMessageUrl?: string | null;
|
|
117
|
-
isDuplicate: boolean;
|
|
118
|
-
duplicateOfId?: string | null;
|
|
119
|
-
}
|
|
120
4
|
|
|
121
5
|
declare type addedNodeMutation = {
|
|
122
6
|
parentId: number;
|
|
@@ -546,6 +430,7 @@ interface Props {
|
|
|
546
430
|
getEnvironment: () => EnvironmentInfo;
|
|
547
431
|
getConsoleLogs: () => ConsoleEntry[];
|
|
548
432
|
getNetworkErrors: () => NetworkEntry[];
|
|
433
|
+
getFormErrors: () => FormErrorEntry[];
|
|
549
434
|
getReplayEvents: () => eventWithTime[];
|
|
550
435
|
getExternalReplayUrl: () => string | undefined;
|
|
551
436
|
initialSelection?: string;
|
|
@@ -555,8 +440,8 @@ interface Props {
|
|
|
555
440
|
onSuccess?: (result: ReportResult) => void;
|
|
556
441
|
onError?: (error: Error) => void;
|
|
557
442
|
}
|
|
558
|
-
declare function FlintModal({ projectKey, serverUrl, user, meta, theme, zIndex, onClose, getEnvironment, getConsoleLogs, getNetworkErrors, getReplayEvents, getExternalReplayUrl, initialSelection, enableScreenshot, statusPageUrl, onBeforeSubmit, onSuccess, onError, }: Props): react_jsx_runtime.JSX.Element;
|
|
443
|
+
declare function FlintModal({ projectKey, serverUrl, user, meta, theme, zIndex, onClose, getEnvironment, getConsoleLogs, getNetworkErrors, getFormErrors, getReplayEvents, getExternalReplayUrl, initialSelection, enableScreenshot, statusPageUrl, onBeforeSubmit, onSuccess, onError, }: Props): react_jsx_runtime.JSX.Element;
|
|
559
444
|
|
|
560
445
|
declare function FlintWidget(props: FlintWidgetProps): react_jsx_runtime.JSX.Element;
|
|
561
446
|
|
|
562
|
-
export { FlintModal,
|
|
447
|
+
export { FlintModal, FlintWidget };
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ import { useCallback, useEffect as useEffect2, useRef as useRef2, useState as us
|
|
|
3
3
|
import { useTranslation } from "react-i18next";
|
|
4
4
|
|
|
5
5
|
// src/api.ts
|
|
6
|
-
import { submitReplay, submitReport } from "@flint
|
|
6
|
+
import { submitReplay, submitReport } from "@diegotsi/flint-core";
|
|
7
7
|
|
|
8
8
|
// src/ScreenAnnotator.tsx
|
|
9
9
|
import { domToCanvas } from "modern-screenshot";
|
|
@@ -148,7 +148,7 @@ function ScreenAnnotator({ zIndex, onCapture, onCancel }) {
|
|
|
148
148
|
}
|
|
149
149
|
|
|
150
150
|
// src/theme.ts
|
|
151
|
-
import { resolveTheme } from "@flint
|
|
151
|
+
import { resolveTheme } from "@diegotsi/flint-core";
|
|
152
152
|
|
|
153
153
|
// src/FlintModal.tsx
|
|
154
154
|
import { Fragment, jsx as jsx2, jsxs as jsxs2 } from "react/jsx-runtime";
|
|
@@ -206,6 +206,7 @@ function FlintModal({
|
|
|
206
206
|
getEnvironment,
|
|
207
207
|
getConsoleLogs,
|
|
208
208
|
getNetworkErrors,
|
|
209
|
+
getFormErrors,
|
|
209
210
|
getReplayEvents,
|
|
210
211
|
getExternalReplayUrl,
|
|
211
212
|
initialSelection = "",
|
|
@@ -264,7 +265,8 @@ function FlintModal({
|
|
|
264
265
|
...meta,
|
|
265
266
|
environment: getEnvironment(),
|
|
266
267
|
consoleLogs: getConsoleLogs(),
|
|
267
|
-
networkErrors: getNetworkErrors()
|
|
268
|
+
networkErrors: getNetworkErrors(),
|
|
269
|
+
formErrors: getFormErrors()
|
|
268
270
|
};
|
|
269
271
|
if (isText) {
|
|
270
272
|
collectedMeta.textIssue = {
|
|
@@ -1139,20 +1141,24 @@ function CheckIcon({ size = 20 }) {
|
|
|
1139
1141
|
}
|
|
1140
1142
|
|
|
1141
1143
|
// src/FlintWidget.tsx
|
|
1144
|
+
import { Flint as Flint2 } from "@diegotsi/flint-core";
|
|
1142
1145
|
import { useCallback as useCallback2, useEffect as useEffect3, useRef as useRef3, useState as useState3 } from "react";
|
|
1143
1146
|
import { I18nextProvider, useTranslation as useTranslation2 } from "react-i18next";
|
|
1144
1147
|
|
|
1145
1148
|
// src/collectors/console.ts
|
|
1146
|
-
import { createConsoleCollector } from "@flint
|
|
1149
|
+
import { createConsoleCollector } from "@diegotsi/flint-core";
|
|
1147
1150
|
|
|
1148
1151
|
// src/collectors/environment.ts
|
|
1149
|
-
import { collectEnvironment } from "@flint
|
|
1152
|
+
import { collectEnvironment } from "@diegotsi/flint-core";
|
|
1153
|
+
|
|
1154
|
+
// src/collectors/formErrors.ts
|
|
1155
|
+
import { createFormErrorCollector } from "@diegotsi/flint-core";
|
|
1150
1156
|
|
|
1151
1157
|
// src/collectors/frustration.ts
|
|
1152
|
-
import { createFrustrationCollector } from "@flint
|
|
1158
|
+
import { createFrustrationCollector } from "@diegotsi/flint-core";
|
|
1153
1159
|
|
|
1154
1160
|
// src/collectors/network.ts
|
|
1155
|
-
import { createNetworkCollector } from "@flint
|
|
1161
|
+
import { createNetworkCollector } from "@diegotsi/flint-core";
|
|
1156
1162
|
|
|
1157
1163
|
// src/i18n/index.ts
|
|
1158
1164
|
import { createInstance } from "i18next";
|
|
@@ -1204,9 +1210,9 @@ widgetI18n.use(initReactI18next).init({
|
|
|
1204
1210
|
var i18n_default = widgetI18n;
|
|
1205
1211
|
|
|
1206
1212
|
// src/store.ts
|
|
1207
|
-
import { getSnapshot, subscribe } from "@flint
|
|
1213
|
+
import { getSnapshot, subscribe } from "@diegotsi/flint-core";
|
|
1208
1214
|
import { useSyncExternalStore } from "react";
|
|
1209
|
-
import {
|
|
1215
|
+
import { _setFormErrorCollector, Flint, flint } from "@diegotsi/flint-core";
|
|
1210
1216
|
function useFlintStore() {
|
|
1211
1217
|
return useSyncExternalStore(subscribe, getSnapshot);
|
|
1212
1218
|
}
|
|
@@ -1236,6 +1242,7 @@ function WidgetContent({
|
|
|
1236
1242
|
enableScreenshot = true,
|
|
1237
1243
|
enableConsole = true,
|
|
1238
1244
|
enableNetwork = true,
|
|
1245
|
+
enableFormErrors = true,
|
|
1239
1246
|
enableFrustration = false,
|
|
1240
1247
|
autoReportFrustration = false,
|
|
1241
1248
|
onBeforeSubmit,
|
|
@@ -1313,31 +1320,42 @@ function WidgetContent({
|
|
|
1313
1320
|
setOpen(true);
|
|
1314
1321
|
onOpen?.();
|
|
1315
1322
|
};
|
|
1323
|
+
const globalInit = Flint2.isInitialized();
|
|
1324
|
+
const global = Flint2.getInstance();
|
|
1316
1325
|
const consoleCollector = useRef3(null);
|
|
1317
1326
|
const networkCollector = useRef3(null);
|
|
1318
1327
|
const replayEvents = useRef3([]);
|
|
1319
1328
|
const stopReplay = useRef3(null);
|
|
1320
|
-
|
|
1321
|
-
consoleCollector.current = createConsoleCollector();
|
|
1322
|
-
consoleCollector.current.start();
|
|
1323
|
-
}
|
|
1324
|
-
if (enableNetwork && !networkCollector.current) {
|
|
1325
|
-
const flintHost = (() => {
|
|
1326
|
-
try {
|
|
1327
|
-
return new URL(serverUrl).hostname;
|
|
1328
|
-
} catch {
|
|
1329
|
-
return "";
|
|
1330
|
-
}
|
|
1331
|
-
})();
|
|
1332
|
-
networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
|
|
1333
|
-
networkCollector.current.start();
|
|
1334
|
-
}
|
|
1329
|
+
const formErrorCollector = useRef3(null);
|
|
1335
1330
|
const frustrationCollector = useRef3(null);
|
|
1336
|
-
if (
|
|
1337
|
-
|
|
1338
|
-
|
|
1331
|
+
if (!globalInit) {
|
|
1332
|
+
if (enableConsole && !consoleCollector.current) {
|
|
1333
|
+
consoleCollector.current = createConsoleCollector();
|
|
1334
|
+
consoleCollector.current.start();
|
|
1335
|
+
}
|
|
1336
|
+
if (enableNetwork && !networkCollector.current) {
|
|
1337
|
+
const flintHost = (() => {
|
|
1338
|
+
try {
|
|
1339
|
+
return new URL(serverUrl).hostname;
|
|
1340
|
+
} catch {
|
|
1341
|
+
return "";
|
|
1342
|
+
}
|
|
1343
|
+
})();
|
|
1344
|
+
networkCollector.current = createNetworkCollector(flintHost ? [flintHost] : []);
|
|
1345
|
+
networkCollector.current.start();
|
|
1346
|
+
}
|
|
1347
|
+
if (enableFormErrors && !formErrorCollector.current) {
|
|
1348
|
+
formErrorCollector.current = createFormErrorCollector();
|
|
1349
|
+
formErrorCollector.current.start();
|
|
1350
|
+
_setFormErrorCollector(formErrorCollector.current);
|
|
1351
|
+
}
|
|
1352
|
+
if (enableFrustration && !frustrationCollector.current) {
|
|
1353
|
+
frustrationCollector.current = createFrustrationCollector();
|
|
1354
|
+
frustrationCollector.current.start();
|
|
1355
|
+
}
|
|
1339
1356
|
}
|
|
1340
1357
|
useEffect3(() => {
|
|
1358
|
+
if (globalInit) return;
|
|
1341
1359
|
let cancelled = false;
|
|
1342
1360
|
if (enableReplay) {
|
|
1343
1361
|
import("rrweb").then(({ record }) => {
|
|
@@ -1358,11 +1376,14 @@ function WidgetContent({
|
|
|
1358
1376
|
cancelled = true;
|
|
1359
1377
|
consoleCollector.current?.stop();
|
|
1360
1378
|
networkCollector.current?.stop();
|
|
1379
|
+
formErrorCollector.current?.stop();
|
|
1380
|
+
_setFormErrorCollector(null);
|
|
1361
1381
|
frustrationCollector.current?.stop();
|
|
1362
1382
|
stopReplay.current?.();
|
|
1363
1383
|
};
|
|
1364
|
-
}, [enableReplay]);
|
|
1384
|
+
}, [enableReplay, globalInit]);
|
|
1365
1385
|
useEffect3(() => {
|
|
1386
|
+
if (globalInit) return;
|
|
1366
1387
|
if (!enableFrustration || !autoReportFrustration || !frustrationCollector.current) return;
|
|
1367
1388
|
const unsubscribe = frustrationCollector.current.onFrustration(async (event) => {
|
|
1368
1389
|
const user2 = resolvedUser;
|
|
@@ -1377,13 +1398,14 @@ function WidgetContent({
|
|
|
1377
1398
|
environment: collectEnvironment(),
|
|
1378
1399
|
consoleLogs: consoleCollector.current?.getEntries() ?? [],
|
|
1379
1400
|
networkErrors: networkCollector.current?.getEntries() ?? [],
|
|
1401
|
+
formErrors: formErrorCollector.current?.getEntries() ?? [],
|
|
1380
1402
|
frustrationEvent: event
|
|
1381
1403
|
}
|
|
1382
1404
|
}).catch(() => {
|
|
1383
1405
|
});
|
|
1384
1406
|
});
|
|
1385
1407
|
return unsubscribe;
|
|
1386
|
-
}, [enableFrustration, autoReportFrustration]);
|
|
1408
|
+
}, [enableFrustration, autoReportFrustration, globalInit]);
|
|
1387
1409
|
const label = buttonLabel ?? t("buttonLabel");
|
|
1388
1410
|
return /* @__PURE__ */ jsxs3(Fragment2, { children: [
|
|
1389
1411
|
/* @__PURE__ */ jsxs3(
|
|
@@ -1481,9 +1503,10 @@ function WidgetContent({
|
|
|
1481
1503
|
pendingSelection.current = "";
|
|
1482
1504
|
},
|
|
1483
1505
|
getEnvironment: collectEnvironment,
|
|
1484
|
-
getConsoleLogs: () => consoleCollector.current?.getEntries() ?? [],
|
|
1485
|
-
getNetworkErrors: () => networkCollector.current?.getEntries() ?? [],
|
|
1486
|
-
|
|
1506
|
+
getConsoleLogs: () => globalInit ? global?.console?.getEntries() ?? [] : consoleCollector.current?.getEntries() ?? [],
|
|
1507
|
+
getNetworkErrors: () => globalInit ? global?.network?.getEntries() ?? [] : networkCollector.current?.getEntries() ?? [],
|
|
1508
|
+
getFormErrors: () => globalInit ? global?.formErrors?.getEntries() ?? [] : formErrorCollector.current?.getEntries() ?? [],
|
|
1509
|
+
getReplayEvents: () => globalInit ? Flint2.getReplayEvents() : [...replayEvents.current],
|
|
1487
1510
|
getExternalReplayUrl,
|
|
1488
1511
|
initialSelection: pendingSelection.current,
|
|
1489
1512
|
enableScreenshot,
|
|
@@ -1535,8 +1558,9 @@ function SparkIcon2() {
|
|
|
1535
1558
|
);
|
|
1536
1559
|
}
|
|
1537
1560
|
export {
|
|
1561
|
+
Flint,
|
|
1538
1562
|
FlintModal,
|
|
1539
1563
|
FlintWidget,
|
|
1540
|
-
|
|
1564
|
+
flint
|
|
1541
1565
|
};
|
|
1542
1566
|
//# sourceMappingURL=index.js.map
|