@diegotsi/flint-core 1.2.0 → 1.3.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/dist/chunk-HVSD45YR.js +29 -0
- package/dist/chunk-HVSD45YR.js.map +1 -0
- package/dist/datadog-I3QKI6Q3.js +9 -0
- package/dist/datadog-I3QKI6Q3.js.map +1 -0
- package/dist/index.cjs +162 -17
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +48 -50
- package/dist/index.d.ts +48 -50
- package/dist/index.js +124 -16
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// src/integrations/datadog.ts
|
|
2
|
+
var DATADOG_BLOCKED_HOSTS = [
|
|
3
|
+
"browser-intake-datadoghq.com",
|
|
4
|
+
"rum.browser-intake-datadoghq.com",
|
|
5
|
+
"logs.browser-intake-datadoghq.com",
|
|
6
|
+
"session-replay.browser-intake-datadoghq.com"
|
|
7
|
+
];
|
|
8
|
+
function createDatadogReplayProvider(site) {
|
|
9
|
+
return () => {
|
|
10
|
+
try {
|
|
11
|
+
const ddRum = window.DD_RUM;
|
|
12
|
+
const ctx = ddRum?.getInternalContext?.();
|
|
13
|
+
if (ctx?.session_id) {
|
|
14
|
+
const ts = Date.now();
|
|
15
|
+
const fromTs = ts - 3e4;
|
|
16
|
+
const toTs = ts + 5e3;
|
|
17
|
+
return `https://${site}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
18
|
+
}
|
|
19
|
+
} catch {
|
|
20
|
+
}
|
|
21
|
+
return void 0;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
export {
|
|
26
|
+
DATADOG_BLOCKED_HOSTS,
|
|
27
|
+
createDatadogReplayProvider
|
|
28
|
+
};
|
|
29
|
+
//# sourceMappingURL=chunk-HVSD45YR.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/integrations/datadog.ts"],"sourcesContent":["/**\n * Datadog RUM integration — opt-in helper.\n *\n * Usage:\n * import { Flint } from \"@diegotsi/flint-core\";\n * import { createDatadogReplayProvider, DATADOG_BLOCKED_HOSTS } from \"@diegotsi/flint-core\";\n *\n * Flint.init({\n * projectKey: \"...\",\n * serverUrl: \"...\",\n * externalReplayProvider: createDatadogReplayProvider(\"app.datadoghq.com\"),\n * blockedHosts: DATADOG_BLOCKED_HOSTS,\n * });\n */\n\n/** Datadog intake hosts to exclude from network capture. */\nexport const DATADOG_BLOCKED_HOSTS = [\n \"browser-intake-datadoghq.com\",\n \"rum.browser-intake-datadoghq.com\",\n \"logs.browser-intake-datadoghq.com\",\n \"session-replay.browser-intake-datadoghq.com\",\n];\n\n/**\n * Creates an `externalReplayProvider` that reads the current Datadog RUM\n * session and returns a deep link to the Session Replay viewer.\n */\nexport function createDatadogReplayProvider(site: string): () => string | undefined {\n return () => {\n try {\n const ddRum = (window as unknown as Record<string, unknown>).DD_RUM as\n | { getInternalContext?: () => { session_id?: string } | undefined }\n | undefined;\n const ctx = ddRum?.getInternalContext?.();\n if (ctx?.session_id) {\n const ts = Date.now();\n const fromTs = ts - 30_000;\n const toTs = ts + 5_000;\n return `https://${site}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;\n }\n } catch {\n // DD_RUM not available — silently skip\n }\n return undefined;\n };\n}\n"],"mappings":";AAgBO,IAAM,wBAAwB;AAAA,EACnC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF;AAMO,SAAS,4BAA4B,MAAwC;AAClF,SAAO,MAAM;AACX,QAAI;AACF,YAAM,QAAS,OAA8C;AAG7D,YAAM,MAAM,OAAO,qBAAqB;AACxC,UAAI,KAAK,YAAY;AACnB,cAAM,KAAK,KAAK,IAAI;AACpB,cAAM,SAAS,KAAK;AACpB,cAAM,OAAO,KAAK;AAClB,eAAO,WAAW,IAAI,wBAAwB,IAAI,UAAU,YAAY,MAAM,UAAU,IAAI;AAAA,MAC9F;AAAA,IACF,QAAQ;AAAA,IAER;AACA,WAAO;AAAA,EACT;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/index.cjs
CHANGED
|
@@ -3,6 +3,9 @@ var __defProp = Object.defineProperty;
|
|
|
3
3
|
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
4
|
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
5
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
+
var __esm = (fn, res) => function __init() {
|
|
7
|
+
return fn && (res = (0, fn[__getOwnPropNames(fn)[0]])(fn = 0)), res;
|
|
8
|
+
};
|
|
6
9
|
var __export = (target, all) => {
|
|
7
10
|
for (var name in all)
|
|
8
11
|
__defProp(target, name, { get: all[name], enumerable: true });
|
|
@@ -17,17 +20,53 @@ var __copyProps = (to, from, except, desc) => {
|
|
|
17
20
|
};
|
|
18
21
|
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
22
|
|
|
23
|
+
// src/integrations/datadog.ts
|
|
24
|
+
var datadog_exports = {};
|
|
25
|
+
__export(datadog_exports, {
|
|
26
|
+
DATADOG_BLOCKED_HOSTS: () => DATADOG_BLOCKED_HOSTS,
|
|
27
|
+
createDatadogReplayProvider: () => createDatadogReplayProvider
|
|
28
|
+
});
|
|
29
|
+
function createDatadogReplayProvider(site) {
|
|
30
|
+
return () => {
|
|
31
|
+
try {
|
|
32
|
+
const ddRum = window.DD_RUM;
|
|
33
|
+
const ctx = ddRum?.getInternalContext?.();
|
|
34
|
+
if (ctx?.session_id) {
|
|
35
|
+
const ts = Date.now();
|
|
36
|
+
const fromTs = ts - 3e4;
|
|
37
|
+
const toTs = ts + 5e3;
|
|
38
|
+
return `https://${site}/rum/replay/sessions/${ctx.session_id}?from_ts=${fromTs}&to_ts=${toTs}&tab=replay&live=false`;
|
|
39
|
+
}
|
|
40
|
+
} catch {
|
|
41
|
+
}
|
|
42
|
+
return void 0;
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
var DATADOG_BLOCKED_HOSTS;
|
|
46
|
+
var init_datadog = __esm({
|
|
47
|
+
"src/integrations/datadog.ts"() {
|
|
48
|
+
"use strict";
|
|
49
|
+
DATADOG_BLOCKED_HOSTS = [
|
|
50
|
+
"browser-intake-datadoghq.com",
|
|
51
|
+
"rum.browser-intake-datadoghq.com",
|
|
52
|
+
"logs.browser-intake-datadoghq.com",
|
|
53
|
+
"session-replay.browser-intake-datadoghq.com"
|
|
54
|
+
];
|
|
55
|
+
}
|
|
56
|
+
});
|
|
57
|
+
|
|
20
58
|
// src/index.ts
|
|
21
59
|
var index_exports = {};
|
|
22
60
|
__export(index_exports, {
|
|
61
|
+
DATADOG_BLOCKED_HOSTS: () => DATADOG_BLOCKED_HOSTS,
|
|
23
62
|
Flint: () => Flint,
|
|
24
63
|
_setFormErrorCollector: () => _setFormErrorCollector,
|
|
25
64
|
collectEnvironment: () => collectEnvironment,
|
|
26
65
|
createConsoleCollector: () => createConsoleCollector,
|
|
66
|
+
createDatadogReplayProvider: () => createDatadogReplayProvider,
|
|
27
67
|
createFormErrorCollector: () => createFormErrorCollector,
|
|
28
68
|
createFrustrationCollector: () => createFrustrationCollector,
|
|
29
69
|
createNetworkCollector: () => createNetworkCollector,
|
|
30
|
-
flint: () => flint,
|
|
31
70
|
getSnapshot: () => getSnapshot,
|
|
32
71
|
resolveTheme: () => resolveTheme,
|
|
33
72
|
submitReplay: () => submitReplay,
|
|
@@ -581,21 +620,85 @@ function createFrustrationCollector(opts) {
|
|
|
581
620
|
|
|
582
621
|
// src/collectors/network.ts
|
|
583
622
|
var MAX_ENTRIES3 = 50;
|
|
584
|
-
var
|
|
623
|
+
var DEFAULT_BLOCKED_HOSTS = [
|
|
585
624
|
"browser-intake-datadoghq.com",
|
|
586
|
-
"
|
|
587
|
-
"
|
|
588
|
-
"
|
|
625
|
+
"datadoghq.com",
|
|
626
|
+
"datadoghq.eu",
|
|
627
|
+
"google.com",
|
|
628
|
+
"googleapis.com",
|
|
629
|
+
"google-analytics.com",
|
|
630
|
+
"googletagmanager.com",
|
|
631
|
+
"gstatic.com",
|
|
632
|
+
"doubleclick.net",
|
|
633
|
+
"facebook.com",
|
|
634
|
+
"facebook.net",
|
|
635
|
+
"hotjar.com",
|
|
636
|
+
"hotjar.io",
|
|
637
|
+
"intercom.io",
|
|
638
|
+
"intercomcdn.com",
|
|
639
|
+
"segment.io",
|
|
640
|
+
"segment.com",
|
|
641
|
+
"mixpanel.com",
|
|
642
|
+
"amplitude.com",
|
|
643
|
+
"sentry.io",
|
|
644
|
+
"fullstory.com",
|
|
645
|
+
"clarity.ms",
|
|
646
|
+
"newrelic.com",
|
|
647
|
+
"nr-data.net",
|
|
648
|
+
"cloudflareinsights.com",
|
|
649
|
+
"heapanalytics.com",
|
|
650
|
+
"posthog.com",
|
|
651
|
+
"logrocket.io",
|
|
652
|
+
"lr-in-prod.com"
|
|
653
|
+
];
|
|
654
|
+
var ASSET_EXTENSIONS = /* @__PURE__ */ new Set([
|
|
655
|
+
".woff",
|
|
656
|
+
".woff2",
|
|
657
|
+
".ttf",
|
|
658
|
+
".otf",
|
|
659
|
+
".eot",
|
|
660
|
+
// fonts
|
|
661
|
+
".png",
|
|
662
|
+
".jpg",
|
|
663
|
+
".jpeg",
|
|
664
|
+
".gif",
|
|
665
|
+
".svg",
|
|
666
|
+
".webp",
|
|
667
|
+
".ico",
|
|
668
|
+
".avif",
|
|
669
|
+
// images
|
|
670
|
+
".css",
|
|
671
|
+
".map",
|
|
672
|
+
// styles & source maps
|
|
673
|
+
".js",
|
|
674
|
+
".mjs",
|
|
675
|
+
// scripts (usually loaded by browser, not app logic)
|
|
676
|
+
".mp3",
|
|
677
|
+
".mp4",
|
|
678
|
+
".webm",
|
|
679
|
+
".ogg"
|
|
680
|
+
// media
|
|
589
681
|
]);
|
|
590
|
-
function
|
|
682
|
+
function isAssetUrl(url) {
|
|
683
|
+
try {
|
|
684
|
+
const pathname = new URL(url, location.href).pathname;
|
|
685
|
+
const ext = pathname.slice(pathname.lastIndexOf(".")).toLowerCase();
|
|
686
|
+
return ASSET_EXTENSIONS.has(ext);
|
|
687
|
+
} catch {
|
|
688
|
+
return false;
|
|
689
|
+
}
|
|
690
|
+
}
|
|
691
|
+
function isBlockedUrl(url, blocked) {
|
|
591
692
|
try {
|
|
592
693
|
const host = new URL(url, location.href).hostname;
|
|
593
|
-
|
|
594
|
-
return all.some((b) => host === b || host.endsWith("." + b));
|
|
694
|
+
return [...blocked].some((b) => host === b || host.endsWith("." + b));
|
|
595
695
|
} catch {
|
|
596
696
|
return false;
|
|
597
697
|
}
|
|
598
698
|
}
|
|
699
|
+
function shouldIgnore(url, blocked) {
|
|
700
|
+
return isBlockedUrl(url, blocked) || isAssetUrl(url);
|
|
701
|
+
}
|
|
599
702
|
function truncateUrl(url) {
|
|
600
703
|
try {
|
|
601
704
|
const u = new URL(url, location.href);
|
|
@@ -607,7 +710,7 @@ function truncateUrl(url) {
|
|
|
607
710
|
}
|
|
608
711
|
function createNetworkCollector(extraBlockedHosts = []) {
|
|
609
712
|
const entries = [];
|
|
610
|
-
const blocked = new Set(extraBlockedHosts);
|
|
713
|
+
const blocked = /* @__PURE__ */ new Set([...DEFAULT_BLOCKED_HOSTS, ...extraBlockedHosts]);
|
|
611
714
|
let origFetch = null;
|
|
612
715
|
let origXHROpen = null;
|
|
613
716
|
let active = false;
|
|
@@ -625,7 +728,7 @@ function createNetworkCollector(extraBlockedHosts = []) {
|
|
|
625
728
|
const url = typeof input === "string" ? input : input instanceof URL ? input.href : input.url;
|
|
626
729
|
const startTime = Date.now();
|
|
627
730
|
const res = await origFetch.call(window, input, init2);
|
|
628
|
-
if (!
|
|
731
|
+
if (!shouldIgnore(url, blocked)) {
|
|
629
732
|
push({
|
|
630
733
|
method,
|
|
631
734
|
url: truncateUrl(url),
|
|
@@ -641,7 +744,7 @@ function createNetworkCollector(extraBlockedHosts = []) {
|
|
|
641
744
|
const startTime = Date.now();
|
|
642
745
|
const urlStr = typeof url === "string" ? url : url.href;
|
|
643
746
|
this.addEventListener("load", () => {
|
|
644
|
-
if (!
|
|
747
|
+
if (!shouldIgnore(urlStr, blocked)) {
|
|
645
748
|
push({
|
|
646
749
|
method: method.toUpperCase(),
|
|
647
750
|
url: truncateUrl(urlStr),
|
|
@@ -666,6 +769,9 @@ function createNetworkCollector(extraBlockedHosts = []) {
|
|
|
666
769
|
};
|
|
667
770
|
}
|
|
668
771
|
|
|
772
|
+
// src/index.ts
|
|
773
|
+
init_datadog();
|
|
774
|
+
|
|
669
775
|
// src/store.ts
|
|
670
776
|
var formErrorCollectorRef = null;
|
|
671
777
|
function _setFormErrorCollector(collector) {
|
|
@@ -729,7 +835,8 @@ function init(config) {
|
|
|
729
835
|
blockedHosts = [],
|
|
730
836
|
frustration: frustrationOpts,
|
|
731
837
|
onFrustration,
|
|
732
|
-
_replayRecorder
|
|
838
|
+
_replayRecorder,
|
|
839
|
+
_collectors
|
|
733
840
|
} = config;
|
|
734
841
|
debugLog(config, "Initializing", {
|
|
735
842
|
serverUrl: config.serverUrl,
|
|
@@ -746,9 +853,10 @@ function init(config) {
|
|
|
746
853
|
return "";
|
|
747
854
|
}
|
|
748
855
|
})();
|
|
749
|
-
const
|
|
856
|
+
const allBlockedHosts = [...blockedHosts, ...flintHost ? [flintHost] : []];
|
|
857
|
+
const consoleCol = enableConsole ? _collectors?.console?.() ?? createConsoleCollector() : null;
|
|
750
858
|
consoleCol?.start();
|
|
751
|
-
const networkCol = enableNetwork ?
|
|
859
|
+
const networkCol = enableNetwork ? _collectors?.network?.(allBlockedHosts) ?? createNetworkCollector(allBlockedHosts) : null;
|
|
752
860
|
networkCol?.start();
|
|
753
861
|
const formErrorsCol = enableFormErrors ? createFormErrorCollector() : null;
|
|
754
862
|
if (formErrorsCol) {
|
|
@@ -789,6 +897,7 @@ function init(config) {
|
|
|
789
897
|
if (instance) instance.stopReplay = stopReplay;
|
|
790
898
|
});
|
|
791
899
|
}
|
|
900
|
+
const getEnvironment = _collectors?.environment ?? collectEnvironment;
|
|
792
901
|
if (frustrationCol && autoReportFrustration) {
|
|
793
902
|
frustrationCol.onFrustration(async (event) => {
|
|
794
903
|
debugLog(config, "Frustration detected, auto-reporting:", event.type, event.details);
|
|
@@ -804,7 +913,7 @@ function init(config) {
|
|
|
804
913
|
source: "auto_capture",
|
|
805
914
|
meta: {
|
|
806
915
|
...config.meta,
|
|
807
|
-
environment:
|
|
916
|
+
environment: getEnvironment(),
|
|
808
917
|
consoleLogs: consoleCol?.getEntries() ?? [],
|
|
809
918
|
networkErrors: networkCol?.getEntries() ?? [],
|
|
810
919
|
formErrors: formErrorsCol?.getEntries() ?? [],
|
|
@@ -816,6 +925,33 @@ function init(config) {
|
|
|
816
925
|
} else if (frustrationCol && onFrustration) {
|
|
817
926
|
frustrationCol.onFrustration(onFrustration);
|
|
818
927
|
}
|
|
928
|
+
if (!config.externalReplayProvider) {
|
|
929
|
+
fetchProjectConfig(config.serverUrl, config.projectKey).then((remote) => {
|
|
930
|
+
if (!instance || !remote?.integrations) return;
|
|
931
|
+
const dd = remote.integrations.datadog;
|
|
932
|
+
if (dd?.enabled && dd.site) {
|
|
933
|
+
Promise.resolve().then(() => (init_datadog(), datadog_exports)).then(({ createDatadogReplayProvider: createDatadogReplayProvider2 }) => {
|
|
934
|
+
if (!instance) return;
|
|
935
|
+
instance.config = {
|
|
936
|
+
...instance.config,
|
|
937
|
+
externalReplayProvider: createDatadogReplayProvider2(dd.site)
|
|
938
|
+
};
|
|
939
|
+
debugLog(config, "Remote Datadog integration loaded:", dd.site);
|
|
940
|
+
});
|
|
941
|
+
}
|
|
942
|
+
}).catch(() => {
|
|
943
|
+
});
|
|
944
|
+
}
|
|
945
|
+
}
|
|
946
|
+
async function fetchProjectConfig(serverUrl, projectKey) {
|
|
947
|
+
try {
|
|
948
|
+
const url = `${serverUrl.replace(/\/$/, "")}/api/v1/project-config`;
|
|
949
|
+
const res = await fetch(url, { headers: { "x-project-key": projectKey } });
|
|
950
|
+
if (!res.ok) return null;
|
|
951
|
+
return res.json();
|
|
952
|
+
} catch {
|
|
953
|
+
return null;
|
|
954
|
+
}
|
|
819
955
|
}
|
|
820
956
|
function shutdown() {
|
|
821
957
|
if (!instance) return;
|
|
@@ -834,9 +970,10 @@ function getInstance() {
|
|
|
834
970
|
return instance;
|
|
835
971
|
}
|
|
836
972
|
function getMeta(extraMeta) {
|
|
973
|
+
const getEnvironment = instance?.config._collectors?.environment ?? collectEnvironment;
|
|
837
974
|
return {
|
|
838
975
|
...extraMeta,
|
|
839
|
-
environment:
|
|
976
|
+
environment: getEnvironment(),
|
|
840
977
|
consoleLogs: instance?.console?.getEntries() ?? [],
|
|
841
978
|
networkErrors: instance?.network?.getEntries() ?? [],
|
|
842
979
|
formErrors: instance?.formErrors?.getEntries() ?? []
|
|
@@ -848,6 +985,12 @@ function getReplayEvents() {
|
|
|
848
985
|
function getConfig() {
|
|
849
986
|
return instance?.config ?? null;
|
|
850
987
|
}
|
|
988
|
+
function getExternalReplayUrl() {
|
|
989
|
+
const storeReplay = getSnapshot().sessionReplay;
|
|
990
|
+
const fromStore = typeof storeReplay === "function" ? storeReplay() : storeReplay;
|
|
991
|
+
if (fromStore) return fromStore;
|
|
992
|
+
return instance?.config.externalReplayProvider?.();
|
|
993
|
+
}
|
|
851
994
|
var Flint = {
|
|
852
995
|
init,
|
|
853
996
|
shutdown,
|
|
@@ -856,6 +999,7 @@ var Flint = {
|
|
|
856
999
|
getMeta,
|
|
857
1000
|
getReplayEvents,
|
|
858
1001
|
getConfig,
|
|
1002
|
+
getExternalReplayUrl,
|
|
859
1003
|
setUser: flint.setUser,
|
|
860
1004
|
setSessionReplay: flint.setSessionReplay,
|
|
861
1005
|
reportFormError: flint.reportFormError
|
|
@@ -901,14 +1045,15 @@ function resolveTheme(theme) {
|
|
|
901
1045
|
}
|
|
902
1046
|
// Annotate the CommonJS export names for ESM import in node:
|
|
903
1047
|
0 && (module.exports = {
|
|
1048
|
+
DATADOG_BLOCKED_HOSTS,
|
|
904
1049
|
Flint,
|
|
905
1050
|
_setFormErrorCollector,
|
|
906
1051
|
collectEnvironment,
|
|
907
1052
|
createConsoleCollector,
|
|
1053
|
+
createDatadogReplayProvider,
|
|
908
1054
|
createFormErrorCollector,
|
|
909
1055
|
createFrustrationCollector,
|
|
910
1056
|
createNetworkCollector,
|
|
911
|
-
flint,
|
|
912
1057
|
getSnapshot,
|
|
913
1058
|
resolveTheme,
|
|
914
1059
|
submitReplay,
|