@sailfish-ai/recorder 1.10.11 → 1.10.13
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/chunks/{chunkSerializer-BCPkBdRj.js → chunkSerializer-CodMnuS3.js} +1 -1
- package/dist/chunks/chunkSerializer-CodMnuS3.js.br +0 -0
- package/dist/chunks/chunkSerializer-CodMnuS3.js.gz +0 -0
- package/dist/chunks/{chunkSerializer-COhHoxJ2.js → chunkSerializer-Dk1eF3S8.js} +1 -1
- package/dist/chunks/chunkSerializer-Dk1eF3S8.js.br +0 -0
- package/dist/chunks/chunkSerializer-Dk1eF3S8.js.gz +0 -0
- package/dist/chunks/{index-DmRBuNoo.js → index-DW416eVj.js} +498 -518
- package/dist/chunks/index-DW416eVj.js.br +0 -0
- package/dist/chunks/index-DW416eVj.js.gz +0 -0
- package/dist/chunks/{index-2nktNgJ_.js → index-DvLh2k6O.js} +319 -280
- package/dist/chunks/index-DvLh2k6O.js.br +0 -0
- package/dist/chunks/index-DvLh2k6O.js.gz +0 -0
- package/dist/headlessDetection.js +29 -0
- package/dist/index.js +24 -10
- package/dist/recorder.cjs +2 -2
- package/dist/recorder.js +40 -39
- package/dist/recorder.js.br +0 -0
- package/dist/recorder.js.gz +0 -0
- package/dist/recording.js +7 -10
- package/dist/types/headlessDetection.d.ts +1 -0
- package/dist/types/index.d.ts +1 -0
- package/package.json +1 -1
- package/dist/chunks/chunkSerializer-BCPkBdRj.js.br +0 -0
- package/dist/chunks/chunkSerializer-BCPkBdRj.js.gz +0 -0
- package/dist/chunks/chunkSerializer-COhHoxJ2.js.br +0 -0
- package/dist/chunks/chunkSerializer-COhHoxJ2.js.gz +0 -0
- package/dist/chunks/index-2nktNgJ_.js.br +0 -0
- package/dist/chunks/index-2nktNgJ_.js.gz +0 -0
- package/dist/chunks/index-DmRBuNoo.js.br +0 -0
- package/dist/chunks/index-DmRBuNoo.js.gz +0 -0
|
@@ -1,5 +1,27 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
1
|
+
"use strict";
|
|
2
|
+
var __create = Object.create;
|
|
3
|
+
var __defProp = Object.defineProperty;
|
|
4
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
5
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
6
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
7
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
8
|
+
var __copyProps = (to, from, except, desc) => {
|
|
9
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
10
|
+
for (let key of __getOwnPropNames(from))
|
|
11
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
12
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
13
|
+
}
|
|
14
|
+
return to;
|
|
15
|
+
};
|
|
16
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
17
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
18
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
19
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
20
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
21
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
22
|
+
mod
|
|
23
|
+
));
|
|
24
|
+
const e = require("reconnecting-websocket"), t = require("@sailfish-rrweb/types");
|
|
3
25
|
function readDebugFlag() {
|
|
4
26
|
var _a;
|
|
5
27
|
try {
|
|
@@ -35,29 +57,29 @@ function uuidv4() {
|
|
|
35
57
|
return ("x" === e2 ? t2 : 3 & t2 | 8).toString(16);
|
|
36
58
|
});
|
|
37
59
|
}
|
|
38
|
-
const n = "X-Sf3-Rid", i = 0, o = 1, s = 2,
|
|
39
|
-
let
|
|
60
|
+
const n = "X-Sf3-Rid", i = 0, o = 1, s = 2, r = 4, a = "recordingEvents";
|
|
61
|
+
let l = null;
|
|
40
62
|
function openDb$1() {
|
|
41
63
|
return (function hasIndexedDB$1() {
|
|
42
64
|
return "undefined" != typeof globalThis && !!globalThis.indexedDB;
|
|
43
|
-
})() ?
|
|
65
|
+
})() ? l || (l = new Promise((e2) => {
|
|
44
66
|
try {
|
|
45
67
|
const t2 = globalThis.indexedDB.open("leapsEventDB", 1);
|
|
46
68
|
t2.onupgradeneeded = () => {
|
|
47
69
|
const e3 = t2.result;
|
|
48
|
-
e3.objectStoreNames.contains(
|
|
70
|
+
e3.objectStoreNames.contains(a) || e3.createObjectStore(a, { keyPath: "id", autoIncrement: true });
|
|
49
71
|
}, t2.onsuccess = () => e2(t2.result), t2.onerror = () => e2(null), t2.onblocked = () => {
|
|
50
72
|
e2(null);
|
|
51
73
|
};
|
|
52
74
|
} catch {
|
|
53
75
|
e2(null);
|
|
54
76
|
}
|
|
55
|
-
}),
|
|
77
|
+
}), l) : Promise.resolve(null);
|
|
56
78
|
}
|
|
57
79
|
function withStore$1(e2, t2) {
|
|
58
80
|
return openDb$1().then((n2) => n2 ? new Promise((i2) => {
|
|
59
81
|
try {
|
|
60
|
-
const o2 = n2.transaction(
|
|
82
|
+
const o2 = n2.transaction(a, e2), s2 = o2.objectStore(a);
|
|
61
83
|
Promise.resolve(t2(s2)).then((e3) => {
|
|
62
84
|
o2.oncomplete = () => i2(e3), o2.onerror = () => i2(null);
|
|
63
85
|
}).catch(() => i2(null));
|
|
@@ -71,28 +93,28 @@ async function deleteEventsByIds(e2) {
|
|
|
71
93
|
for (const n2 of e2) t2.delete(n2);
|
|
72
94
|
});
|
|
73
95
|
}
|
|
74
|
-
const
|
|
75
|
-
let
|
|
96
|
+
const c = "notifyMessages";
|
|
97
|
+
let d = null;
|
|
76
98
|
function openDb() {
|
|
77
99
|
return (function hasIndexedDB() {
|
|
78
100
|
return "undefined" != typeof globalThis && !!globalThis.indexedDB;
|
|
79
|
-
})() ?
|
|
101
|
+
})() ? d || (d = new Promise((e2) => {
|
|
80
102
|
try {
|
|
81
103
|
const t2 = globalThis.indexedDB.open("leapsNotifyDB", 1);
|
|
82
104
|
t2.onupgradeneeded = () => {
|
|
83
105
|
const e3 = t2.result;
|
|
84
|
-
e3.objectStoreNames.contains(
|
|
106
|
+
e3.objectStoreNames.contains(c) || e3.createObjectStore(c, { keyPath: "id", autoIncrement: true });
|
|
85
107
|
}, t2.onsuccess = () => e2(t2.result), t2.onerror = () => e2(null), t2.onblocked = () => e2(null);
|
|
86
108
|
} catch {
|
|
87
109
|
e2(null);
|
|
88
110
|
}
|
|
89
|
-
}),
|
|
111
|
+
}), d) : Promise.resolve(null);
|
|
90
112
|
}
|
|
91
113
|
async function withStore(e2, t2) {
|
|
92
114
|
const n2 = await openDb();
|
|
93
115
|
return n2 ? new Promise((i2) => {
|
|
94
116
|
try {
|
|
95
|
-
const o2 = n2.transaction(
|
|
117
|
+
const o2 = n2.transaction(c, e2), s2 = o2.objectStore(c);
|
|
96
118
|
Promise.resolve(t2(s2)).then((e3) => {
|
|
97
119
|
o2.oncomplete = () => i2(e3), o2.onerror = () => i2(null);
|
|
98
120
|
}).catch(() => i2(null));
|
|
@@ -111,25 +133,25 @@ async function deleteNotifyMessageById(e2) {
|
|
|
111
133
|
t2.delete(e2);
|
|
112
134
|
});
|
|
113
135
|
}
|
|
114
|
-
const
|
|
115
|
-
let
|
|
136
|
+
const u = "undefined" != typeof globalThis && void 0 !== globalThis.window, p = "undefined" != typeof globalThis && void 0 !== globalThis.document, f = "undefined" != typeof globalThis && "localStorage" in globalThis, g = "undefined" != typeof globalThis && "sessionStorage" in globalThis, m = "sailfishSessionId", h = "__sailfish_refresh__";
|
|
137
|
+
let y = null;
|
|
116
138
|
function getOrSetSessionId() {
|
|
117
|
-
if (!
|
|
118
|
-
if (
|
|
119
|
-
const e2 = window.name.startsWith(
|
|
139
|
+
if (!u) return uuidv4();
|
|
140
|
+
if (y) return y;
|
|
141
|
+
const e2 = window.name.startsWith(h);
|
|
120
142
|
if (e2 && (window.name = window.name.substring(20)), e2) {
|
|
121
|
-
const e3 = window.sessionStorage.getItem(
|
|
122
|
-
if (e3) return
|
|
143
|
+
const e3 = window.sessionStorage.getItem(m);
|
|
144
|
+
if (e3) return y = e3, e3;
|
|
123
145
|
}
|
|
124
146
|
const t2 = uuidv4();
|
|
125
|
-
|
|
147
|
+
y = t2;
|
|
126
148
|
try {
|
|
127
|
-
window.sessionStorage.setItem(
|
|
149
|
+
window.sessionStorage.setItem(m, t2);
|
|
128
150
|
} catch (e3) {
|
|
129
151
|
}
|
|
130
152
|
return t2;
|
|
131
153
|
}
|
|
132
|
-
let
|
|
154
|
+
let b = false;
|
|
133
155
|
function buildBatches(e2, t2, n2) {
|
|
134
156
|
const i2 = {};
|
|
135
157
|
for (const t3 of e2) {
|
|
@@ -139,40 +161,39 @@ function buildBatches(e2, t2, n2) {
|
|
|
139
161
|
const o2 = [];
|
|
140
162
|
for (const e3 in i2) {
|
|
141
163
|
const s2 = i2[e3];
|
|
142
|
-
let
|
|
164
|
+
let r2 = [], a2 = 0;
|
|
143
165
|
for (const e4 of s2) {
|
|
144
166
|
const i3 = t2(e4);
|
|
145
|
-
|
|
167
|
+
a2 + i3 > n2 && (r2.length > 0 && (o2.push(r2), r2 = [], a2 = 0), i3 > n2) || (r2.push(e4), a2 += i3);
|
|
146
168
|
}
|
|
147
|
-
|
|
169
|
+
r2.length > 0 && o2.push(r2);
|
|
148
170
|
}
|
|
149
171
|
return o2;
|
|
150
172
|
}
|
|
151
173
|
function eventSize(e2) {
|
|
152
174
|
return JSON.stringify(e2).length;
|
|
153
175
|
}
|
|
154
|
-
let v = Date.now;
|
|
155
176
|
function withAppUrlMetadata(e2) {
|
|
156
177
|
var _a;
|
|
157
178
|
return { ...e2 ?? {}, appUrl: (e2 == null ? void 0 : e2.appUrl) ?? ((_a = window == null ? void 0 : window.location) == null ? void 0 : _a.href) };
|
|
158
179
|
}
|
|
159
|
-
/[1-9][0-9]{12}/.test(Date.now().toString()) || (
|
|
160
|
-
const S = readDebugFlag(),
|
|
161
|
-
let
|
|
162
|
-
const
|
|
180
|
+
exports.nowTimestamp = Date.now, /[1-9][0-9]{12}/.test(Date.now().toString()) || (exports.nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime());
|
|
181
|
+
const S = readDebugFlag(), v = "per_session";
|
|
182
|
+
let w = null, k = null, x = false, I = null, T = null, E = "", C = "", $ = false;
|
|
183
|
+
const F = [];
|
|
163
184
|
function onNavigationChange(e2) {
|
|
164
|
-
|
|
185
|
+
F.push(e2);
|
|
165
186
|
}
|
|
166
187
|
function _updateHrefCache() {
|
|
167
|
-
|
|
168
|
-
for (const e2 of
|
|
188
|
+
E = window.location.href, C = window.location.origin + window.location.pathname;
|
|
189
|
+
for (const e2 of F) try {
|
|
169
190
|
e2();
|
|
170
191
|
} catch (e3) {
|
|
171
192
|
}
|
|
172
193
|
}
|
|
173
194
|
function ensureHrefCache() {
|
|
174
|
-
if (
|
|
175
|
-
|
|
195
|
+
if ($ || "undefined" == typeof window) return;
|
|
196
|
+
$ = true, _updateHrefCache(), window.addEventListener("popstate", _updateHrefCache), window.addEventListener("hashchange", _updateHrefCache);
|
|
176
197
|
const e2 = history.pushState;
|
|
177
198
|
history.pushState = function(...t3) {
|
|
178
199
|
e2.apply(this, t3), _updateHrefCache();
|
|
@@ -183,48 +204,48 @@ function ensureHrefCache() {
|
|
|
183
204
|
};
|
|
184
205
|
}
|
|
185
206
|
function getCachedHref() {
|
|
186
|
-
return
|
|
207
|
+
return E || ("undefined" != typeof window ? window.location.href : "");
|
|
187
208
|
}
|
|
188
209
|
function getCachedHrefNoQuery() {
|
|
189
|
-
return
|
|
210
|
+
return C || ("undefined" != typeof window ? window.location.origin + window.location.pathname : "");
|
|
190
211
|
}
|
|
191
|
-
const
|
|
192
|
-
let
|
|
212
|
+
const L = [];
|
|
213
|
+
let M = null;
|
|
193
214
|
function queueEventForIDB(e2) {
|
|
194
|
-
|
|
215
|
+
L.push(e2), L.length >= 50 ? _flushIDBQueue() : M || (M = setTimeout(_flushIDBQueue, 100));
|
|
195
216
|
}
|
|
196
217
|
function _flushIDBQueue() {
|
|
197
|
-
if (
|
|
218
|
+
if (M && (clearTimeout(M), M = null), 0 === L.length) return;
|
|
198
219
|
!(async function saveEventsToIDB(e2) {
|
|
199
220
|
await withStore$1("readwrite", async (t2) => {
|
|
200
221
|
for (const n2 of e2) t2.add({ timestamp: Date.now(), data: n2 });
|
|
201
222
|
});
|
|
202
|
-
})(
|
|
223
|
+
})(L.splice(0));
|
|
203
224
|
}
|
|
204
|
-
let
|
|
205
|
-
const
|
|
225
|
+
let A = false, R = null, D = null, _ = false;
|
|
226
|
+
const P = "sailfish_funcspan_global_state";
|
|
206
227
|
function wsSendPayload(e2) {
|
|
207
|
-
if (!isWebSocketOpen(
|
|
208
|
-
if (
|
|
209
|
-
return
|
|
228
|
+
if (!isWebSocketOpen(k)) return false;
|
|
229
|
+
if (w) try {
|
|
230
|
+
return w.postMessage({ type: "send", payload: e2 }), true;
|
|
210
231
|
} catch {
|
|
211
232
|
return false;
|
|
212
233
|
}
|
|
213
234
|
try {
|
|
214
|
-
return
|
|
235
|
+
return k.send(JSON.stringify(e2)), true;
|
|
215
236
|
} catch {
|
|
216
237
|
return false;
|
|
217
238
|
}
|
|
218
239
|
}
|
|
219
240
|
function wsSendRaw(e2) {
|
|
220
|
-
if (!isWebSocketOpen(
|
|
221
|
-
if (
|
|
222
|
-
return
|
|
241
|
+
if (!isWebSocketOpen(k)) return false;
|
|
242
|
+
if (w) try {
|
|
243
|
+
return w.postMessage({ type: "sendRaw", payload: e2 }), true;
|
|
223
244
|
} catch {
|
|
224
245
|
return false;
|
|
225
246
|
}
|
|
226
247
|
try {
|
|
227
|
-
return
|
|
248
|
+
return k.send(e2), true;
|
|
228
249
|
} catch {
|
|
229
250
|
return false;
|
|
230
251
|
}
|
|
@@ -233,7 +254,7 @@ function saveGlobalFuncSpanState(e2, t2) {
|
|
|
233
254
|
try {
|
|
234
255
|
if ("undefined" == typeof localStorage) return;
|
|
235
256
|
const n2 = { enabled: e2, expirationTimestampMs: t2, savedAt: Date.now() };
|
|
236
|
-
localStorage.setItem(
|
|
257
|
+
localStorage.setItem(P, JSON.stringify(n2)), S && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
|
|
237
258
|
} catch (e3) {
|
|
238
259
|
S && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
|
|
239
260
|
}
|
|
@@ -241,22 +262,22 @@ function saveGlobalFuncSpanState(e2, t2) {
|
|
|
241
262
|
function clearGlobalFuncSpanState() {
|
|
242
263
|
try {
|
|
243
264
|
if ("undefined" == typeof localStorage) return;
|
|
244
|
-
localStorage.removeItem(
|
|
265
|
+
localStorage.removeItem(P), S && console.log("[Sailfish] Cleared funcSpan state from localStorage");
|
|
245
266
|
} catch (e2) {
|
|
246
267
|
S && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
|
|
247
268
|
}
|
|
248
269
|
}
|
|
249
270
|
function clearStaleFuncSpanState() {
|
|
250
|
-
|
|
271
|
+
A = false, D = null, _ = false, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
|
|
251
272
|
}
|
|
252
|
-
let
|
|
273
|
+
let B = false;
|
|
253
274
|
function restoreFuncSpanState() {
|
|
254
|
-
if (
|
|
255
|
-
|
|
275
|
+
if (B) return;
|
|
276
|
+
B = true;
|
|
256
277
|
const e2 = (function loadGlobalFuncSpanState() {
|
|
257
278
|
try {
|
|
258
279
|
if ("undefined" == typeof localStorage) return null;
|
|
259
|
-
const e3 = localStorage.getItem(
|
|
280
|
+
const e3 = localStorage.getItem(P);
|
|
260
281
|
if (!e3) return null;
|
|
261
282
|
const t2 = JSON.parse(e3);
|
|
262
283
|
return S && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
|
|
@@ -264,8 +285,8 @@ function restoreFuncSpanState() {
|
|
|
264
285
|
return S && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
|
|
265
286
|
}
|
|
266
287
|
})();
|
|
267
|
-
if (e2 && e2.enabled) if (
|
|
268
|
-
Date.now() >=
|
|
288
|
+
if (e2 && e2.enabled) if (A = true, D = e2.expirationTimestampMs, _ = false, S && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: D }), null !== D) {
|
|
289
|
+
Date.now() >= D ? (A = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Persisted tracking already expired, cleared state")) : S && console.log("[Sailfish] Function span tracking is active and valid (temporary until WebSocket confirms)");
|
|
269
290
|
} else S && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
|
|
270
291
|
}
|
|
271
292
|
function isWebSocketOpen(e2) {
|
|
@@ -278,7 +299,7 @@ async function flushNotifyQueue() {
|
|
|
278
299
|
n2.onsuccess = () => t2(n2.result), n2.onerror = () => t2([]);
|
|
279
300
|
})) ?? [];
|
|
280
301
|
})();
|
|
281
|
-
if (isWebSocketOpen(
|
|
302
|
+
if (isWebSocketOpen(k)) try {
|
|
282
303
|
for (const t2 of e2) {
|
|
283
304
|
if (!wsSendRaw(t2.value)) break;
|
|
284
305
|
await deleteNotifyMessageById(t2.id);
|
|
@@ -287,9 +308,9 @@ async function flushNotifyQueue() {
|
|
|
287
308
|
}
|
|
288
309
|
}
|
|
289
310
|
async function flushBufferedEvents() {
|
|
290
|
-
if (isWebSocketOpen(
|
|
311
|
+
if (isWebSocketOpen(k)) if (I) await I;
|
|
291
312
|
else {
|
|
292
|
-
|
|
313
|
+
I = (async () => {
|
|
293
314
|
var _a, _b;
|
|
294
315
|
const e2 = await (async function getAllIndexedEvents() {
|
|
295
316
|
return await withStore$1("readonly", (e3) => new Promise((t3) => {
|
|
@@ -304,7 +325,7 @@ async function flushBufferedEvents() {
|
|
|
304
325
|
for (const e3 of Object.values(t2)) {
|
|
305
326
|
const t3 = buildBatches(e3, (e4) => eventSize(e4.data), 52428800);
|
|
306
327
|
for (const e4 of t3) {
|
|
307
|
-
if (!isWebSocketOpen(
|
|
328
|
+
if (!isWebSocketOpen(k)) break;
|
|
308
329
|
const t4 = e4.map((e5) => (e5.data.appUrl || (e5.data.appUrl = getCachedHref()), e5.data)), n2 = e4.map((e5) => e5.id).filter((e5) => null != e5);
|
|
309
330
|
try {
|
|
310
331
|
wsSendPayload({ type: "events", events: t4, mapUuid: window.sfMapUuid }) && await deleteEventsByIds(n2);
|
|
@@ -314,44 +335,44 @@ async function flushBufferedEvents() {
|
|
|
314
335
|
}
|
|
315
336
|
})();
|
|
316
337
|
try {
|
|
317
|
-
await
|
|
338
|
+
await I;
|
|
318
339
|
} finally {
|
|
319
|
-
|
|
340
|
+
I = null;
|
|
320
341
|
}
|
|
321
342
|
}
|
|
322
343
|
}
|
|
323
344
|
function sendEvent(e2) {
|
|
324
|
-
e2.app_url || (e2.app_url = getCachedHref()), !
|
|
345
|
+
e2.app_url || (e2.app_url = getCachedHref()), !x && isWebSocketOpen(k) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
|
|
325
346
|
}
|
|
326
347
|
function handleWsOpen() {
|
|
327
|
-
S && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (
|
|
348
|
+
S && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (A ? "ENABLED" : "DISABLED"))), (async () => {
|
|
328
349
|
try {
|
|
329
|
-
|
|
350
|
+
x = true, await flushNotifyQueue(), await flushBufferedEvents();
|
|
330
351
|
} finally {
|
|
331
|
-
|
|
352
|
+
x = false;
|
|
332
353
|
}
|
|
333
|
-
null !=
|
|
354
|
+
null != T && clearInterval(T), T = window.setInterval(() => {
|
|
334
355
|
flushBufferedEvents();
|
|
335
356
|
}, 2e3);
|
|
336
357
|
})();
|
|
337
358
|
}
|
|
338
359
|
function handleWsClose() {
|
|
339
|
-
null !=
|
|
360
|
+
null != T && (clearInterval(T), T = null), S && console.log("[Sailfish] WebSocket closed");
|
|
340
361
|
}
|
|
341
362
|
function handleWsMessage(e2) {
|
|
342
363
|
try {
|
|
343
364
|
const t2 = JSON.parse(e2);
|
|
344
|
-
if ("funcSpanTrackingControl" === t2.type) if (S && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !==
|
|
365
|
+
if ("funcSpanTrackingControl" === t2.type) if (S && console.log("[Sailfish] Received funcSpanTrackingControl message:", { enabled: t2.enabled, timeoutSeconds: t2.timeoutSeconds, expirationTimestampMs: t2.expirationTimestampMs }), null !== R && (window.clearTimeout(R), R = null), A = t2.enabled, _ = false, S && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
|
|
345
366
|
if (t2.expirationTimestampMs) {
|
|
346
|
-
|
|
347
|
-
const e3 = Date.now(), n2 =
|
|
348
|
-
S && console.log(`[Sailfish] Server expiration timestamp: ${
|
|
349
|
-
|
|
350
|
-
}, n2)) : (
|
|
367
|
+
D = t2.expirationTimestampMs;
|
|
368
|
+
const e3 = Date.now(), n2 = D - e3;
|
|
369
|
+
S && console.log(`[Sailfish] Server expiration timestamp: ${D}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, D), R = window.setTimeout(() => {
|
|
370
|
+
_ || (A = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] GLOBAL function span tracking auto-disabled at server expiration time"), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), S && console.log("[Sailfish] Notified backend that function span tracking expired"));
|
|
371
|
+
}, n2)) : (A = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Tracking already expired, not enabling"));
|
|
351
372
|
} else {
|
|
352
373
|
const e3 = t2.timeoutSeconds || 3600;
|
|
353
|
-
e3 > 0 && (
|
|
354
|
-
|
|
374
|
+
e3 > 0 && (D = Date.now() + 1e3 * e3, saveGlobalFuncSpanState(true, D), R = window.setTimeout(() => {
|
|
375
|
+
_ || (A = false, D = null, clearGlobalFuncSpanState(), S && console.log(`[Sailfish] GLOBAL function span tracking auto-disabled after ${e3}s (legacy)`), wsSendPayload({ type: "funcSpanTrackingExpired", sessionId: getOrSetSessionId(), expiredAt: Date.now() }), S && console.log("[Sailfish] Notified backend that function span tracking expired (legacy timeout)"));
|
|
355
376
|
}, 1e3 * e3));
|
|
356
377
|
}
|
|
357
378
|
try {
|
|
@@ -360,18 +381,18 @@ function handleWsMessage(e2) {
|
|
|
360
381
|
} catch (e3) {
|
|
361
382
|
S && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
|
|
362
383
|
}
|
|
363
|
-
} else
|
|
384
|
+
} else D = null, clearGlobalFuncSpanState();
|
|
364
385
|
} catch (e3) {
|
|
365
386
|
}
|
|
366
387
|
}
|
|
367
388
|
function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
|
|
368
389
|
ensureHrefCache();
|
|
369
|
-
const
|
|
390
|
+
const r2 = (function getWebSocketHost(e2) {
|
|
370
391
|
const t3 = new URL(e2);
|
|
371
392
|
return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
|
|
372
393
|
})(t2);
|
|
373
|
-
let
|
|
374
|
-
if (o2 && (
|
|
394
|
+
let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${r2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.10.13`;
|
|
395
|
+
if (o2 && (a2 += `&envValue=${encodeURIComponent(o2)}`), w = s2 ? (function tryCreateWsWorker() {
|
|
375
396
|
if ("undefined" == typeof Worker) return null;
|
|
376
397
|
try {
|
|
377
398
|
const e2 = new Blob(['\nvar ws = null;\nvar wsUrl = "";\nvar reconnectTimer = null;\nvar reconnectDelay = 1000;\nvar MAX_RECONNECT_DELAY = 30000;\nvar CONNECTION_TIMEOUT = 30000;\nvar queue = [];\nvar MAX_QUEUE = 500;\n\nfunction enqueue(str) {\n if (queue.length >= MAX_QUEUE) queue.shift();\n queue.push(str);\n}\n\nfunction drain() {\n while (queue.length > 0) {\n if (!ws || ws.readyState !== 1) break;\n try { ws.send(queue.shift()); } catch (e) { break; }\n }\n}\n\nfunction connect() {\n if (ws && (ws.readyState === 0 || ws.readyState === 1)) return;\n try { ws = new WebSocket(wsUrl); } catch (e) { scheduleReconnect(); return; }\n var tid = setTimeout(function() { if (ws && ws.readyState === 0) ws.close(); }, CONNECTION_TIMEOUT);\n ws.onopen = function() {\n clearTimeout(tid);\n reconnectDelay = 1000;\n drain();\n postMessage({ type: "open" });\n };\n ws.onclose = function() {\n clearTimeout(tid);\n ws = null;\n postMessage({ type: "close" });\n scheduleReconnect();\n };\n ws.onerror = function() {};\n ws.onmessage = function(e) {\n postMessage({ type: "message", data: e.data });\n };\n}\n\nfunction scheduleReconnect() {\n if (reconnectTimer) return;\n reconnectTimer = setTimeout(function() {\n reconnectTimer = null;\n reconnectDelay = Math.min(reconnectDelay * 1.5, MAX_RECONNECT_DELAY);\n connect();\n }, reconnectDelay);\n}\n\nself.onmessage = function(e) {\n var msg = e.data;\n if (msg.type === "init") {\n wsUrl = msg.wsUrl;\n connect();\n } else if (msg.type === "send") {\n try {\n var s = JSON.stringify(msg.payload);\n if (ws && ws.readyState === 1) { ws.send(s); }\n else { enqueue(s); }\n } catch (e) {}\n } else if (msg.type === "sendRaw") {\n if (ws && ws.readyState === 1) {\n try { ws.send(msg.payload); } catch (e) { enqueue(msg.payload); }\n } else { enqueue(msg.payload); }\n } else if (msg.type === "close") {\n if (reconnectTimer) { clearTimeout(reconnectTimer); reconnectTimer = null; }\n if (ws) { ws.close(); ws = null; }\n }\n};\n'], { type: "application/javascript" }), t3 = URL.createObjectURL(e2), n3 = new Worker(t3);
|
|
@@ -379,96 +400,85 @@ function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
|
|
|
379
400
|
} catch {
|
|
380
401
|
return null;
|
|
381
402
|
}
|
|
382
|
-
})() : null,
|
|
383
|
-
const e2 =
|
|
384
|
-
t3.readyState = WebSocket.CLOSED, e2.postMessage({ type: "close" }), e2.terminate(),
|
|
403
|
+
})() : null, w) {
|
|
404
|
+
const e2 = w, t3 = { readyState: WebSocket.CONNECTING, close: () => {
|
|
405
|
+
t3.readyState = WebSocket.CLOSED, e2.postMessage({ type: "close" }), e2.terminate(), w = null, null != T && (clearInterval(T), T = null);
|
|
385
406
|
} };
|
|
386
|
-
return
|
|
407
|
+
return k = t3, w.onmessage = (e3) => {
|
|
387
408
|
const n3 = e3.data;
|
|
388
409
|
"open" === n3.type ? (t3.readyState = WebSocket.OPEN, handleWsOpen()) : "close" === n3.type ? (t3.readyState = WebSocket.CLOSED, handleWsClose()) : "message" === n3.type && handleWsMessage(n3.data);
|
|
389
|
-
},
|
|
410
|
+
}, w.onerror = () => {
|
|
390
411
|
S && console.warn("[Sailfish] WebSocket worker error");
|
|
391
|
-
},
|
|
412
|
+
}, w.postMessage({ type: "init", wsUrl: a2 }), S && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
|
|
392
413
|
}
|
|
393
414
|
S && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
|
|
394
|
-
const l2 = new e(
|
|
415
|
+
const l2 = new e(a2, [], { connectionTimeout: 3e4 }), c2 = { get readyState() {
|
|
395
416
|
return l2.readyState;
|
|
396
417
|
}, close: () => {
|
|
397
|
-
l2.close(), null !=
|
|
418
|
+
l2.close(), null != T && (clearInterval(T), T = null);
|
|
398
419
|
} };
|
|
399
|
-
return
|
|
420
|
+
return k = c2, l2.addEventListener("open", () => handleWsOpen()), l2.addEventListener("close", () => handleWsClose()), l2.addEventListener("message", (e2) => handleWsMessage(e2.data)), c2;
|
|
400
421
|
}
|
|
401
422
|
function sendMessage(e2) {
|
|
402
|
-
"sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()),
|
|
423
|
+
"sessionId" in e2 || (e2.sessionId = getOrSetSessionId()), e2.app_url || (e2.app_url = getCachedHref()), x || !isWebSocketOpen(k) ? saveNotifyMessageToIDB(JSON.stringify(e2)) : wsSendPayload(e2) || saveNotifyMessageToIDB(JSON.stringify(e2));
|
|
403
424
|
}
|
|
404
425
|
function enableFunctionSpanTracking() {
|
|
405
|
-
if (S && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"),
|
|
406
|
-
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType:
|
|
426
|
+
if (S && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), A = true, _ = true, D = null, null !== R && (window.clearTimeout(R), R = null), isWebSocketOpen(k)) {
|
|
427
|
+
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: v });
|
|
407
428
|
} else S && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
|
|
408
429
|
}
|
|
409
430
|
function disableFunctionSpanTracking() {
|
|
410
|
-
if (S && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(
|
|
411
|
-
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType:
|
|
431
|
+
if (S && console.log("[Sailfish] disableFunctionSpanTracking() called - Report Issue recording stopped"), isWebSocketOpen(k)) {
|
|
432
|
+
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: false, configurationType: v });
|
|
412
433
|
} else console.warn("[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end");
|
|
413
|
-
|
|
434
|
+
_ && (A = false, _ = false, D = null, S && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== R && (window.clearTimeout(R), R = null);
|
|
414
435
|
}
|
|
415
436
|
function isFunctionSpanTrackingEnabled() {
|
|
416
|
-
return
|
|
437
|
+
return A;
|
|
417
438
|
}
|
|
418
439
|
function initializeFunctionSpanTrackingFromApi(e2) {
|
|
419
|
-
e2 && !
|
|
440
|
+
e2 && !A ? (A = true, _ = false, D = null, S && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && A && (A = false, _ = false, D = null, S && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
|
|
420
441
|
}
|
|
421
442
|
function getFuncSpanHeader() {
|
|
422
|
-
if (!
|
|
423
|
-
if (null !==
|
|
424
|
-
if (Date.now() >=
|
|
443
|
+
if (!A) return null;
|
|
444
|
+
if (null !== D) {
|
|
445
|
+
if (Date.now() >= D) return A = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
|
|
425
446
|
}
|
|
426
447
|
return { name: "X-Sf3-FunctionSpanCaptureOverride", value: "1-1-10-10-1-1.0-1-0-0" };
|
|
427
448
|
}
|
|
428
|
-
const
|
|
429
|
-
let
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
U && U.userId === e2 && JSON.stringify(U.traits) === JSON.stringify(t2) || (U = { userId: e2, traits: t2, overwrite: n2 }, sendMessage(i2));
|
|
433
|
-
}
|
|
434
|
-
function addOrUpdateMetadata(e2) {
|
|
435
|
-
const t2 = { type: "addOrUpdateMetadata", metadata: e2 };
|
|
436
|
-
q && JSON.stringify(q) === JSON.stringify(e2) || (q = e2, sendMessage(t2));
|
|
437
|
-
}
|
|
438
|
-
function trackingEvent(e2) {
|
|
439
|
-
sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: v() });
|
|
440
|
-
}
|
|
441
|
-
let H = null;
|
|
442
|
-
const N = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
|
|
449
|
+
const j = Object.freeze(Object.defineProperty({ __proto__: null, clearStaleFuncSpanState, disableFunctionSpanTracking, enableFunctionSpanTracking, ensureHrefCache, flushBufferedEvents, getCachedHref, getCachedHrefNoQuery, getFuncSpanHeader, initializeFunctionSpanTrackingFromApi, initializeWebSocket, isFunctionSpanTrackingEnabled, onNavigationChange, restoreFuncSpanState, sendEvent, sendMessage }, Symbol.toStringTag, { value: "Module" }));
|
|
450
|
+
let O = null, U = null;
|
|
451
|
+
let z = null;
|
|
452
|
+
const H = ["https://api.ipify.org?format=json", "https://api.ip.sb/jsonip", "https://api4.my-ip.io/ip.json"];
|
|
443
453
|
function fetchAndSendIp(e2) {
|
|
444
|
-
|
|
445
|
-
for (const e3 of
|
|
454
|
+
z !== e2 && (z = e2, (async () => {
|
|
455
|
+
for (const e3 of H) try {
|
|
446
456
|
const t2 = new AbortController(), n2 = setTimeout(() => t2.abort(), 5e3), i2 = await fetch(e3, { signal: t2.signal });
|
|
447
457
|
if (clearTimeout(n2), !i2.ok) continue;
|
|
448
458
|
const o2 = await i2.json(), s2 = o2.ip || o2.origin || null;
|
|
449
|
-
if (s2 && "string" == typeof s2 && s2.length <= 45) return void sendMessage({ type: "visitorIp", ip: s2, timestamp:
|
|
459
|
+
if (s2 && "string" == typeof s2 && s2.length <= 45) return void sendMessage({ type: "visitorIp", ip: s2, timestamp: exports.nowTimestamp() });
|
|
450
460
|
} catch {
|
|
451
461
|
}
|
|
452
|
-
|
|
462
|
+
z = null;
|
|
453
463
|
})().catch(() => {
|
|
454
|
-
|
|
464
|
+
z = null;
|
|
455
465
|
}));
|
|
456
466
|
}
|
|
457
|
-
let
|
|
467
|
+
let N = null;
|
|
458
468
|
async function getSourceMapModule() {
|
|
459
|
-
return
|
|
469
|
+
return N || (N = await import("source-map-js")), N;
|
|
460
470
|
}
|
|
461
|
-
const
|
|
471
|
+
const q = /* @__PURE__ */ new Map(), W = /(?:\(|\s|^)(https?:\/\/[^)\s]+|\/[^)\s]+|[^)\s]+)?\/?([^/]+\.js)(?:\?[^:)]*)?:(\d+):(\d+)/;
|
|
462
472
|
async function getConsumerFor(e2, t2) {
|
|
463
473
|
const n2 = (e2 || `/assets/${t2}`).split("?")[0], i2 = [`${n2}.map`, n2.replace(/\.js$/, ".js.map"), `/assets/${t2}.map`], { SourceMapConsumer: o2 } = await getSourceMapModule();
|
|
464
474
|
for (const e3 of i2) try {
|
|
465
|
-
if (
|
|
475
|
+
if (q.has(e3)) return q.get(e3);
|
|
466
476
|
const t3 = await fetch(e3);
|
|
467
477
|
if (!t3.ok) continue;
|
|
468
478
|
const n3 = await t3.json();
|
|
469
479
|
if (!n3 || !n3.mappings || !n3.sources) continue;
|
|
470
480
|
const i3 = await new o2(n3);
|
|
471
|
-
return
|
|
481
|
+
return q.set(e3, i3), i3;
|
|
472
482
|
} catch {
|
|
473
483
|
}
|
|
474
484
|
return null;
|
|
@@ -480,13 +490,13 @@ async function captureError(e2, t2 = false) {
|
|
|
480
490
|
if (!e3) return ["No stack trace available"];
|
|
481
491
|
const t3 = Array.isArray(e3) ? e3 : e3.split("\n"), n3 = [];
|
|
482
492
|
for (const e4 of t3) {
|
|
483
|
-
const t4 = e4.match(
|
|
493
|
+
const t4 = e4.match(W);
|
|
484
494
|
if (!t4) {
|
|
485
495
|
n3.push(e4);
|
|
486
496
|
continue;
|
|
487
497
|
}
|
|
488
|
-
const [, i3, o3, s3,
|
|
489
|
-
if (!Number.isFinite(
|
|
498
|
+
const [, i3, o3, s3, r3] = t4, a3 = parseInt(s3, 10), l2 = Math.max(0, parseInt(r3, 10) - 1);
|
|
499
|
+
if (!Number.isFinite(a3) || !Number.isFinite(l2)) {
|
|
490
500
|
n3.push(e4 + " [Invalid line/column]");
|
|
491
501
|
continue;
|
|
492
502
|
}
|
|
@@ -496,35 +506,35 @@ async function captureError(e2, t2 = false) {
|
|
|
496
506
|
continue;
|
|
497
507
|
}
|
|
498
508
|
const { SourceMapConsumer: d2 } = await getSourceMapModule();
|
|
499
|
-
let u2 = c2.originalPositionFor({ line:
|
|
500
|
-
if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c2.originalPositionFor({ line:
|
|
509
|
+
let u2 = c2.originalPositionFor({ line: a3, column: l2, bias: d2.GREATEST_LOWER_BOUND });
|
|
510
|
+
if (!u2.source || null == u2.line) for (let e5 = 1; e5 <= 20 && (u2 = c2.originalPositionFor({ line: a3, column: Math.max(0, l2 - e5), bias: d2.GREATEST_LOWER_BOUND }), !u2.source || null == u2.line); e5++) ;
|
|
501
511
|
if (u2.source && null != u2.line) {
|
|
502
512
|
const e5 = u2.name || "anonymous";
|
|
503
513
|
n3.push(`${u2.source}:${u2.line}:${u2.column ?? 0} (${e5})`);
|
|
504
514
|
} else n3.push(`${e4} [No mapping found in ${o3}]`);
|
|
505
515
|
}
|
|
506
516
|
return n3;
|
|
507
|
-
})(i2), s2 = o2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")),
|
|
508
|
-
sendMessage({ type: "event", event: { type: 6, timestamp:
|
|
517
|
+
})(i2), s2 = o2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), r2 = s2.length > 0 ? s2 : o2, a2 = Date.now();
|
|
518
|
+
sendMessage({ type: "event", event: { type: 6, timestamp: a2, data: { payload: { message: n2, stack: i2, trace: r2, filteredStack: s2, userAgent: navigator.userAgent, url: window.location.href, timestamp: a2, level: "error" } } } });
|
|
509
519
|
}
|
|
510
|
-
const
|
|
511
|
-
const
|
|
520
|
+
const K = readDebugFlag();
|
|
521
|
+
const G = readDebugFlag();
|
|
512
522
|
function sendGraphQLRequest(e2, t2, n2, i2 = 5, o2 = 2e3, s2 = 2) {
|
|
513
|
-
const
|
|
514
|
-
return
|
|
523
|
+
const r2 = `${n2.backendApi}/graphql/?apiKey=${n2.apiKey}`;
|
|
524
|
+
return G && console.log(`Initial GraphQL request for ${e2} at ${r2}`), (function exponentialBackoff(e3, t3, n3 = 5, i3 = 2e3, o3 = 2) {
|
|
515
525
|
let s3 = 0;
|
|
516
526
|
const attemptRequest = async () => {
|
|
517
527
|
try {
|
|
518
528
|
return await e3();
|
|
519
529
|
} catch (e4) {
|
|
520
530
|
if (s3++, s3 > n3) throw e4;
|
|
521
|
-
const
|
|
522
|
-
return
|
|
531
|
+
const r3 = i3 * Math.pow(o3, s3 - 1);
|
|
532
|
+
return K && console.log(`Attempt ${s3} failed: ${t3}; Retrying in ${r3}ms...`), await new Promise((e5) => setTimeout(e5, r3)), attemptRequest();
|
|
523
533
|
}
|
|
524
534
|
};
|
|
525
535
|
return attemptRequest();
|
|
526
|
-
})(() => fetch(
|
|
527
|
-
if (
|
|
536
|
+
})(() => fetch(r2, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ operationName: e2, query: t2, variables: n2 }) }).then((e3) => {
|
|
537
|
+
if (G && console.log(`Received response with status: ${e3.status}`), !e3.ok) throw new Error(`GraphQL request failed with status ${e3.status}`);
|
|
528
538
|
return e3.json();
|
|
529
539
|
}), "Sending GraphQL request to Sailfish AI", i2, o2, s2);
|
|
530
540
|
}
|
|
@@ -534,24 +544,24 @@ function fetchCaptureSettings(e2, t2) {
|
|
|
534
544
|
function fetchFunctionSpanTrackingEnabled(e2, t2) {
|
|
535
545
|
return sendGraphQLRequest("GetFunctionSpanTrackingEnabledFromApiKey", "\n query GetFunctionSpanTrackingEnabledFromApiKey($apiKey: String!) {\n isFunctionSpanTrackingEnabledFromApiKey(apiKey: $apiKey)\n }\n ", { apiKey: e2, backendApi: t2 });
|
|
536
546
|
}
|
|
537
|
-
function startRecordingSession(e2, t2, n2, i2, o2, s2,
|
|
538
|
-
return sendGraphQLRequest("StartSession", "mutation StartSession(\n $apiKey: UUID!,\n $recordingSessionId: UUID!,\n $serviceIdentifier: String!,\n $serviceVersion: String,\n $mapUuid: String,\n $gitSha: String,\n $library: String,\n $serviceAdditionalMetadata: JSON,\n $startRecordingFilePath: String,\n $startRecordingLineNumber: Int\n ) {\n startRecordingSession(\n companyApiKey: $apiKey,\n sessionId: $recordingSessionId,\n serviceIdentifier: $serviceIdentifier,\n serviceVersion: $serviceVersion,\n mapUuid: $mapUuid,\n gitSha: $gitSha,\n library: $library,\n serviceAdditionalMetadata: $serviceAdditionalMetadata,\n startRecordingFilePath: $startRecordingFilePath,\n startRecordingLineNumber: $startRecordingLineNumber\n ) {\n id\n }\n }", { apiKey: e2, recordingSessionId: t2, backendApi: n2, serviceIdentifier: i2, serviceVersion: o2, mapUuid: s2, gitSha:
|
|
547
|
+
function startRecordingSession(e2, t2, n2, i2, o2, s2, r2, a2, l2) {
|
|
548
|
+
return sendGraphQLRequest("StartSession", "mutation StartSession(\n $apiKey: UUID!,\n $recordingSessionId: UUID!,\n $serviceIdentifier: String!,\n $serviceVersion: String,\n $mapUuid: String,\n $gitSha: String,\n $library: String,\n $serviceAdditionalMetadata: JSON,\n $startRecordingFilePath: String,\n $startRecordingLineNumber: Int\n ) {\n startRecordingSession(\n companyApiKey: $apiKey,\n sessionId: $recordingSessionId,\n serviceIdentifier: $serviceIdentifier,\n serviceVersion: $serviceVersion,\n mapUuid: $mapUuid,\n gitSha: $gitSha,\n library: $library,\n serviceAdditionalMetadata: $serviceAdditionalMetadata,\n startRecordingFilePath: $startRecordingFilePath,\n startRecordingLineNumber: $startRecordingLineNumber\n ) {\n id\n }\n }", { apiKey: e2, recordingSessionId: t2, backendApi: n2, serviceIdentifier: i2, serviceVersion: o2, mapUuid: s2, gitSha: r2, library: a2, serviceAdditionalMetadata: l2, startRecordingFilePath: null, startRecordingLineNumber: null });
|
|
539
549
|
}
|
|
540
550
|
function sendDomainsToNotPropagateHeaderTo(e2, t2, n2) {
|
|
541
551
|
return sendGraphQLRequest("DomainsToNotPassHeaderTo", "mutation DomainsToNotPassHeaderTo($apiKey: String!, $domains: [String!]!) {\n domainsToNotPassHeaderTo(apiKey: $apiKey, domains: $domains)\n }", { apiKey: e2, domains: t2, backendApi: n2 });
|
|
542
552
|
}
|
|
543
|
-
function createTriageFromRecorder(e2, t2, n2, i2, o2, s2,
|
|
544
|
-
return sendGraphQLRequest("CreateTriageFromRecorder", "mutation CreateTriageFromRecorder(\n $apiKey: String!,\n $recordingSessionId: String!,\n $timestampStart: String!,\n $timestampEnd: String!,\n $description: String,\n $triageSource: TriageSourceEnum\n ) {\n createTriageFromRecorder(\n apiKey: $apiKey,\n recordingSessionId: $recordingSessionId,\n timestampStart: $timestampStart,\n timestampEnd: $timestampEnd,\n description: $description,\n triageSource: $triageSource\n ) {\n id\n }\n }\n ", { apiKey: e2, recordingSessionId: n2, timestampStart: i2, timestampEnd: o2, description: s2, triageSource:
|
|
553
|
+
function createTriageFromRecorder(e2, t2, n2, i2, o2, s2, r2) {
|
|
554
|
+
return sendGraphQLRequest("CreateTriageFromRecorder", "mutation CreateTriageFromRecorder(\n $apiKey: String!,\n $recordingSessionId: String!,\n $timestampStart: String!,\n $timestampEnd: String!,\n $description: String,\n $triageSource: TriageSourceEnum\n ) {\n createTriageFromRecorder(\n apiKey: $apiKey,\n recordingSessionId: $recordingSessionId,\n timestampStart: $timestampStart,\n timestampEnd: $timestampEnd,\n description: $description,\n triageSource: $triageSource\n ) {\n id\n }\n }\n ", { apiKey: e2, recordingSessionId: n2, timestampStart: i2, timestampEnd: o2, description: s2, triageSource: r2, backendApi: t2 });
|
|
545
555
|
}
|
|
546
556
|
function fetchEngineeringTicketPlatformIntegrations(e2, t2) {
|
|
547
557
|
return sendGraphQLRequest("GetEngineeringTicketPlatformIntegrationsFromApiKey", "query GetEngineeringTicketPlatformIntegrationsFromApiKey($apiKey: String!) {\n getEngineeringTicketPlatformIntegrationsFromApiKey(apiKey: $apiKey) {\n pushAutoIdentifiedIssues\n provider\n clientId\n defaultPriority\n defaultProject\n defaultTeam\n primaryCloudId\n installed\n projects\n teams\n workflowStates\n webhookState\n clouds\n labels\n sprints\n users\n fieldConfigurations\n invalidFields\n jiraReporterAccountId\n }\n }", { apiKey: e2, backendApi: t2 });
|
|
548
558
|
}
|
|
549
|
-
function createTriageAndIssueFromRecorder(e2, t2, n2, i2, o2, s2,
|
|
550
|
-
return sendGraphQLRequest("CreateTriageAndIssueFromRecorder", "mutation CreateTriageAndIssueFromRecorder(\n $apiKey: String!,\n $recordingSessionId: String!,\n $timestampStart: String!,\n $timestampEnd: String!,\n $description: String,\n $issueName: String,\n $issueDescription: String,\n $createEngineeringTicket: Boolean,\n $teamId: String,\n $projectId: String,\n $priority: Int,\n $labels: [String!],\n $issueType: String,\n $customFields: JSON,\n $triageSource: TriageSourceEnum\n ) {\n createTriageAndIssueFromRecorder(\n apiKey: $apiKey,\n recordingSessionId: $recordingSessionId,\n timestampStart: $timestampStart,\n timestampEnd: $timestampEnd,\n description: $description,\n issueName: $issueName,\n issueDescription: $issueDescription,\n createEngineeringTicket: $createEngineeringTicket,\n teamId: $teamId,\n projectId: $projectId,\n priority: $priority,\n labels: $labels,\n issueType: $issueType,\n customFields: $customFields,\n triageSource: $triageSource\n ) {\n id\n title\n }\n }\n ", { apiKey: e2, recordingSessionId: n2, timestampStart: i2, timestampEnd: o2, description: s2, issueName:
|
|
559
|
+
function createTriageAndIssueFromRecorder(e2, t2, n2, i2, o2, s2, r2, a2, l2, c2, d2, u2, p2, f2, g2, m2) {
|
|
560
|
+
return sendGraphQLRequest("CreateTriageAndIssueFromRecorder", "mutation CreateTriageAndIssueFromRecorder(\n $apiKey: String!,\n $recordingSessionId: String!,\n $timestampStart: String!,\n $timestampEnd: String!,\n $description: String,\n $issueName: String,\n $issueDescription: String,\n $createEngineeringTicket: Boolean,\n $teamId: String,\n $projectId: String,\n $priority: Int,\n $labels: [String!],\n $issueType: String,\n $customFields: JSON,\n $triageSource: TriageSourceEnum\n ) {\n createTriageAndIssueFromRecorder(\n apiKey: $apiKey,\n recordingSessionId: $recordingSessionId,\n timestampStart: $timestampStart,\n timestampEnd: $timestampEnd,\n description: $description,\n issueName: $issueName,\n issueDescription: $issueDescription,\n createEngineeringTicket: $createEngineeringTicket,\n teamId: $teamId,\n projectId: $projectId,\n priority: $priority,\n labels: $labels,\n issueType: $issueType,\n customFields: $customFields,\n triageSource: $triageSource\n ) {\n id\n title\n }\n }\n ", { apiKey: e2, recordingSessionId: n2, timestampStart: i2, timestampEnd: o2, description: s2, issueName: r2, issueDescription: a2, createEngineeringTicket: l2, teamId: c2, projectId: d2, priority: u2, labels: p2, issueType: f2, customFields: g2, triageSource: m2, backendApi: t2 });
|
|
551
561
|
}
|
|
552
|
-
const
|
|
562
|
+
const V = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
|
|
553
563
|
function shouldSkipFrame(e2) {
|
|
554
|
-
return
|
|
564
|
+
return V.some((t2) => e2.includes(t2));
|
|
555
565
|
}
|
|
556
566
|
function normalizeFilePath(e2) {
|
|
557
567
|
let t2 = e2;
|
|
@@ -617,8 +627,8 @@ function yieldToMain() {
|
|
|
617
627
|
var _a;
|
|
618
628
|
return "undefined" != typeof globalThis && ((_a = globalThis.scheduler) == null ? void 0 : _a.yield) ? globalThis.scheduler.yield() : new Promise((e2) => setTimeout(e2, 0));
|
|
619
629
|
}
|
|
620
|
-
let
|
|
621
|
-
const
|
|
630
|
+
let Q = null;
|
|
631
|
+
const J = "sailfishSanitize", X = "zendesk_chat", Z = "Zendesk";
|
|
622
632
|
function zE_safe(...e2) {
|
|
623
633
|
try {
|
|
624
634
|
if ((function hasZendesk() {
|
|
@@ -634,13 +644,13 @@ function maskInputFn(e2, t2) {
|
|
|
634
644
|
const n2 = { creditCard: /\b(?:\d[ -]*?){13,16}\b/, ssn: /\b\d{3}-\d{2}-\d{4}\b/ };
|
|
635
645
|
return t2.closest(".mask") ? "*".repeat(e2.length) : t2.hasAttribute("data-cc") || ((_a = t2.getAttribute("autocomplete")) == null ? void 0 : _a.startsWith("cc-")) || n2.creditCard.test(e2) ? "**** **** **** " + e2.slice(-4) : t2.hasAttribute("data-ssn") || n2.ssn.test(e2) ? "***-**-" + e2.slice(-4) : t2.hasAttribute("data-dob") ? "**/**/" + e2.slice(-4) : e2;
|
|
636
646
|
}
|
|
637
|
-
let
|
|
647
|
+
let Y = true, ee = null, te = null, ne = null, ie = null;
|
|
638
648
|
function invalidateUrlCache() {
|
|
639
|
-
|
|
649
|
+
Y = true;
|
|
640
650
|
}
|
|
641
|
-
const getUrlAndStoredUuids = () => (
|
|
642
|
-
|
|
643
|
-
})(), { page_visit_uuid:
|
|
651
|
+
const getUrlAndStoredUuids = () => (Y && (function _refreshSessionStorageCache() {
|
|
652
|
+
ee = sessionStorage.getItem("pageVisitUUID"), te = sessionStorage.getItem("prevPageVisitUUID"), ne = sessionStorage.getItem("tabVisibilityChanged"), ie = sessionStorage.getItem("tabVisibilityState"), Y = false;
|
|
653
|
+
})(), { page_visit_uuid: ee, prev_page_visit_uuid: te, href: getCachedHrefNoQuery(), tabVisibilityChanged: ne, tabVisibilityState: ie });
|
|
644
654
|
function initializeDomContentEvents(e2) {
|
|
645
655
|
document.addEventListener("readystatechange", () => {
|
|
646
656
|
const t2 = { type: 24, data: { source: 0, info: "" }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() };
|
|
@@ -654,9 +664,7 @@ function initializeDomContentEvents(e2) {
|
|
|
654
664
|
t2.data.info && sendEvent(t2);
|
|
655
665
|
}), document.addEventListener("DOMContentLoaded", () => {
|
|
656
666
|
sendEvent({ type: 24, data: { source: o }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() });
|
|
657
|
-
}), window.addEventListener("
|
|
658
|
-
sendEvent({ type: 24, data: { source: a }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() });
|
|
659
|
-
}), window.addEventListener("unload", () => {
|
|
667
|
+
}), window.addEventListener("pagehide", () => {
|
|
660
668
|
sendEvent({ type: 24, data: { source: r }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() });
|
|
661
669
|
});
|
|
662
670
|
}
|
|
@@ -665,12 +673,12 @@ async function initializeConsolePlugin(e2, n2) {
|
|
|
665
673
|
await yieldToMain();
|
|
666
674
|
const { name: o2, observer: s2 } = i2(e2);
|
|
667
675
|
s2((e3) => {
|
|
668
|
-
const i3 = e3, [s3,
|
|
669
|
-
sendEvent({ type: t.Plugin, timestamp: Date.now(), data: { plugin: o2, payload: u2 }, sessionId: n2, ...getUrlAndStoredUuids() });
|
|
676
|
+
const i3 = e3, [s3, r2] = getCallerLocationFromTrace(i3 == null ? void 0 : i3.trace, 0), [a2, l2] = getCallerLocation(2), c2 = s3 ?? a2, d2 = r2 ?? l2, u2 = { ...i3, sourceFile: c2, sourceLine: d2 };
|
|
677
|
+
sendEvent({ type: t.EventType.Plugin, timestamp: Date.now(), data: { plugin: o2, payload: u2 }, sessionId: n2, ...getUrlAndStoredUuids() });
|
|
670
678
|
}, window, e2);
|
|
671
679
|
}
|
|
672
|
-
async function initializeRecording(e2, n2, i2, o2, s2,
|
|
673
|
-
const c2 = initializeWebSocket(n2, i2, o2, s2,
|
|
680
|
+
async function initializeRecording(e2, n2, i2, o2, s2, r2 = true, a2 = false, l2 = false) {
|
|
681
|
+
const c2 = initializeWebSocket(n2, i2, o2, s2, a2);
|
|
674
682
|
try {
|
|
675
683
|
const n3 = (function createThrottledEmit(e3, t2 = 1e3) {
|
|
676
684
|
if (!e3) return { emit: (e4) => sendEvent(e4), flush: () => {
|
|
@@ -696,30 +704,30 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
|
|
|
696
704
|
Object.assign(e3, getUrlAndStoredUuids()), e3.sessionId = o2, n3.emit(e3);
|
|
697
705
|
}, startHeavyWork = async () => {
|
|
698
706
|
if (true === e2.enableFiberTracking) try {
|
|
699
|
-
const { installFiberHook: e3, processExistingTree: t2 } = await
|
|
707
|
+
const { installFiberHook: e3, processExistingTree: t2 } = await Promise.resolve().then(() => require("./fiberHook-CEzmPkx_.js"));
|
|
700
708
|
e3(), t2(), console.log("[Sailfish] React Fiber tracking enabled");
|
|
701
709
|
} catch (e3) {
|
|
702
710
|
console.warn("[Sailfish] Failed to enable Fiber tracking:", e3);
|
|
703
711
|
}
|
|
704
712
|
const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
|
|
705
|
-
if (
|
|
706
|
-
const { chunkedSnapshot: i3 } = await
|
|
713
|
+
if (Q = n4, await yieldToMain(), l2) {
|
|
714
|
+
const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-CodMnuS3.js")), o3 = n4.mirror;
|
|
707
715
|
let s3 = true;
|
|
708
|
-
const
|
|
716
|
+
const r3 = [];
|
|
709
717
|
n4({ emit(e3) {
|
|
710
|
-
s3 ?
|
|
711
|
-
}, maskInputOptions: { text: true }, maskInputFn, maskTextClass:
|
|
712
|
-
const
|
|
718
|
+
s3 ? r3.push(e3) : emitWithContext(e3);
|
|
719
|
+
}, maskInputOptions: { text: true }, maskInputFn, maskTextClass: J, ...e2, recordDOM: false });
|
|
720
|
+
const a3 = Date.now(), l3 = await i3(document, o3, { chunkSize: 500, maxChunkMs: 16, blockClass: e2.blockClass, blockSelector: e2.blockSelector, maskTextClass: e2.maskTextClass ?? J, maskTextSelector: e2.maskTextSelector });
|
|
713
721
|
if (l3) {
|
|
714
|
-
emitWithContext({ type: t.Meta, data: { href: window.location.href, width: document.documentElement.clientWidth || document.body.clientWidth, height: document.documentElement.clientHeight || document.body.clientHeight }, timestamp:
|
|
715
|
-
for (const e3 of
|
|
722
|
+
emitWithContext({ type: t.EventType.Meta, data: { href: window.location.href, width: document.documentElement.clientWidth || document.body.clientWidth, height: document.documentElement.clientHeight || document.body.clientHeight }, timestamp: a3 }), emitWithContext({ type: t.EventType.FullSnapshot, data: { node: l3, initialOffset: { left: void 0 !== window.pageXOffset ? window.pageXOffset : document.documentElement.scrollLeft, top: void 0 !== window.pageYOffset ? window.pageYOffset : document.documentElement.scrollTop } }, timestamp: a3 });
|
|
723
|
+
for (const e3 of r3) emitWithContext(e3);
|
|
716
724
|
s3 = false;
|
|
717
725
|
} else console.warn("[Sailfish] chunkSnapshot serialization failed; session continues without initial DOM snapshot"), s3 = false;
|
|
718
726
|
} else n4({ emit(e3) {
|
|
719
727
|
emitWithContext(e3);
|
|
720
|
-
}, maskInputOptions: { text: true }, maskInputFn, maskTextClass:
|
|
728
|
+
}, maskInputOptions: { text: true }, maskInputFn, maskTextClass: J, ...e2 });
|
|
721
729
|
};
|
|
722
|
-
if (
|
|
730
|
+
if (r2) {
|
|
723
731
|
let e3 = false;
|
|
724
732
|
const startOnce = () => {
|
|
725
733
|
e3 || (e3 = true, startHeavyWork());
|
|
@@ -749,11 +757,11 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
|
|
|
749
757
|
zE_safe("messenger:set", "conversationTags", [`sailfish-session-${o2}`]);
|
|
750
758
|
});
|
|
751
759
|
const handleWidgetOpen = () => {
|
|
752
|
-
|
|
760
|
+
Q == null ? void 0 : Q.addSailfishEvent(t.EventType.SailfishCustom, { action: "customer support chat opened", element_id: X, provider: Z });
|
|
753
761
|
}, handleWidgetClose = () => {
|
|
754
|
-
|
|
762
|
+
Q == null ? void 0 : Q.addSailfishEvent(t.EventType.SailfishCustom, { action: "customer support chat closed", element_id: X, provider: Z });
|
|
755
763
|
}, handleUnreadMessages = (e3) => {
|
|
756
|
-
|
|
764
|
+
Q == null ? void 0 : Q.addSailfishEvent(t.EventType.SailfishCustom, { action: "zendesk unreadmessages", element_id: X, provider: Z });
|
|
757
765
|
};
|
|
758
766
|
suppressConsoleLogsDuringCall(() => {
|
|
759
767
|
zE_safe("messenger:on", "open", handleWidgetOpen), zE_safe("messenger:on", "close", handleWidgetClose), zE_safe("messenger:on", "unreadMessages", handleUnreadMessages);
|
|
@@ -764,7 +772,7 @@ async function initializeRecording(e2, n2, i2, o2, s2, a2 = true, r2 = false, l2
|
|
|
764
772
|
}
|
|
765
773
|
return c2;
|
|
766
774
|
}
|
|
767
|
-
const
|
|
775
|
+
const oe = [(e2) => (function checkNextJs() {
|
|
768
776
|
try {
|
|
769
777
|
if (void 0 !== globalThis.__NEXT_DATA__) return "nextjs";
|
|
770
778
|
} catch {
|
|
@@ -826,35 +834,35 @@ const ae = [(e2) => (function checkNextJs() {
|
|
|
826
834
|
}
|
|
827
835
|
return null;
|
|
828
836
|
}];
|
|
829
|
-
const
|
|
830
|
-
let
|
|
831
|
-
const
|
|
837
|
+
const se = ["jira", "linear", "zendesk"];
|
|
838
|
+
let re = null;
|
|
839
|
+
const ae = /* @__PURE__ */ new Map();
|
|
832
840
|
function getIntegrationData() {
|
|
833
|
-
return
|
|
841
|
+
return re;
|
|
834
842
|
}
|
|
835
843
|
function hasValidIntegration() {
|
|
836
|
-
return null !==
|
|
844
|
+
return null !== re && true === re.installed;
|
|
837
845
|
}
|
|
838
846
|
function resolveIntegration(e2) {
|
|
839
847
|
var _a;
|
|
840
848
|
if ((e2 == null ? void 0 : e2.errors) && e2.errors.length > 0) return console.error("GraphQL errors fetching integrations:", e2.errors), null;
|
|
841
849
|
const t2 = (_a = e2 == null ? void 0 : e2.data) == null ? void 0 : _a.getEngineeringTicketPlatformIntegrationsFromApiKey, n2 = (t2 || []).filter((e3) => {
|
|
842
850
|
var _a2;
|
|
843
|
-
return
|
|
851
|
+
return se.includes(((_a2 = e3.provider) == null ? void 0 : _a2.toLowerCase()) || "") && true === e3.installed;
|
|
844
852
|
});
|
|
845
853
|
if (0 === n2.length) return console.warn("No valid installed integrations found"), null;
|
|
846
854
|
const i2 = n2.find((e3) => {
|
|
847
855
|
var _a2;
|
|
848
856
|
return "jira" === ((_a2 = e3.provider) == null ? void 0 : _a2.toLowerCase());
|
|
849
857
|
}) || n2[0];
|
|
850
|
-
return (i2 == null ? void 0 : i2.primaryCloudId) &&
|
|
858
|
+
return (i2 == null ? void 0 : i2.primaryCloudId) && ae.set(i2.primaryCloudId, i2), i2;
|
|
851
859
|
}
|
|
852
860
|
async function refreshIntegrationData(e2, t2) {
|
|
853
861
|
try {
|
|
854
862
|
const n2 = resolveIntegration(await fetchEngineeringTicketPlatformIntegrations(e2, t2));
|
|
855
|
-
return
|
|
863
|
+
return re = n2, n2;
|
|
856
864
|
} catch (e3) {
|
|
857
|
-
return console.error("Error refreshing integration data:", e3),
|
|
865
|
+
return console.error("Error refreshing integration data:", e3), re;
|
|
858
866
|
}
|
|
859
867
|
}
|
|
860
868
|
function populateSelectOptions(e2, t2, n2) {
|
|
@@ -889,8 +897,8 @@ function populateSprintOptions(e2, t2, n2) {
|
|
|
889
897
|
}), n2 && (e2.value = n2);
|
|
890
898
|
}
|
|
891
899
|
function getSprintFieldId() {
|
|
892
|
-
if (!(
|
|
893
|
-
const e2 = Array.isArray(
|
|
900
|
+
if (!(re == null ? void 0 : re.fieldConfigurations)) return "customfield_10020";
|
|
901
|
+
const e2 = Array.isArray(re.fieldConfigurations) ? re.fieldConfigurations : [];
|
|
894
902
|
for (const t2 of e2) {
|
|
895
903
|
const e3 = (t2.fields || []).find((e4) => {
|
|
896
904
|
var _a;
|
|
@@ -902,12 +910,12 @@ function getSprintFieldId() {
|
|
|
902
910
|
}
|
|
903
911
|
function updateIssueTypeOptions(e2, t2) {
|
|
904
912
|
var _a;
|
|
905
|
-
if (!(
|
|
913
|
+
if (!(re == null ? void 0 : re.projects) || !t2) {
|
|
906
914
|
e2.innerHTML = "";
|
|
907
915
|
const t3 = document.createElement("option");
|
|
908
916
|
return t3.value = "", t3.disabled = true, t3.selected = true, t3.textContent = "Select project first...", t3.style.color = "#9ca3af", e2.appendChild(t3), void (e2.style.color = "#9ca3af");
|
|
909
917
|
}
|
|
910
|
-
const n2 =
|
|
918
|
+
const n2 = re.projects.find((e3) => e3.id === t2);
|
|
911
919
|
if (!n2 || !n2.issue_types) {
|
|
912
920
|
e2.innerHTML = "";
|
|
913
921
|
const t3 = document.createElement("option");
|
|
@@ -931,58 +939,58 @@ function updateIssueTypeOptions(e2, t2) {
|
|
|
931
939
|
}
|
|
932
940
|
}
|
|
933
941
|
function getFieldsForProject(e2, t2) {
|
|
934
|
-
if (!(
|
|
935
|
-
const n2 = Array.isArray(
|
|
942
|
+
if (!(re == null ? void 0 : re.fieldConfigurations) || !e2) return [];
|
|
943
|
+
const n2 = Array.isArray(re.fieldConfigurations) ? re.fieldConfigurations.find((n3) => n3.project_key === e2 && (!t2 || n3.issue_type_id === t2)) : re.fieldConfigurations[e2];
|
|
936
944
|
return n2 && n2.fields ? n2.fields : [];
|
|
937
945
|
}
|
|
938
946
|
function getUsers() {
|
|
939
|
-
return (
|
|
947
|
+
return (re == null ? void 0 : re.users) ? re.users : [];
|
|
940
948
|
}
|
|
941
949
|
function getProjectsForTeam(e2) {
|
|
942
|
-
if (!
|
|
943
|
-
const t2 =
|
|
950
|
+
if (!re) return [];
|
|
951
|
+
const t2 = re.teams && Array.isArray(re.teams) && re.teams.length > 0;
|
|
944
952
|
if (t2 && e2) {
|
|
945
|
-
const t3 =
|
|
953
|
+
const t3 = re.teams.find((t4) => t4.id === e2);
|
|
946
954
|
return (t3 == null ? void 0 : t3.projects) || [];
|
|
947
955
|
}
|
|
948
|
-
return !t2 &&
|
|
956
|
+
return !t2 && re.projects ? re.projects : [];
|
|
949
957
|
}
|
|
950
958
|
function updateFormWithIntegrationData(e2) {
|
|
951
959
|
var _a;
|
|
952
|
-
if (!
|
|
953
|
-
const t2 =
|
|
954
|
-
n2 && t2 && (populateSelectOptions(n2,
|
|
960
|
+
if (!re) return e2;
|
|
961
|
+
const t2 = re.teams && Array.isArray(re.teams) && re.teams.length > 0, n2 = document.getElementById("sf-eng-ticket-team");
|
|
962
|
+
n2 && t2 && (populateSelectOptions(n2, re.teams, re.defaultTeam), e2.engTicketTeam ? n2.value = e2.engTicketTeam : e2.engTicketTeam = n2.value);
|
|
955
963
|
const i2 = document.getElementById("sf-eng-ticket-project");
|
|
956
964
|
if (i2) {
|
|
957
|
-
populateSelectOptions(i2, t2 ? getProjectsForTeam(e2.engTicketTeam) :
|
|
965
|
+
populateSelectOptions(i2, t2 ? getProjectsForTeam(e2.engTicketTeam) : re.projects || [], re.defaultProject), e2.engTicketProject ? i2.value = e2.engTicketProject : e2.engTicketProject = i2.value;
|
|
958
966
|
}
|
|
959
967
|
const o2 = document.getElementById("sf-eng-ticket-priority");
|
|
960
|
-
o2 && (populatePriorityOptions(o2,
|
|
961
|
-
const s2 = document.getElementById("sf-eng-ticket-sprint"),
|
|
962
|
-
s2 &&
|
|
963
|
-
const
|
|
964
|
-
return
|
|
965
|
-
}
|
|
966
|
-
const
|
|
967
|
-
if (!
|
|
968
|
+
o2 && (populatePriorityOptions(o2, re.provider || "", re.defaultPriority), e2.engTicketPriority ? o2.value = String(e2.engTicketPriority) : e2.engTicketPriority = Number(o2.value));
|
|
969
|
+
const s2 = document.getElementById("sf-eng-ticket-sprint"), r2 = "jira" === ((_a = re.provider) == null ? void 0 : _a.toLowerCase());
|
|
970
|
+
s2 && r2 && re.sprints && populateSprintOptions(s2, re.sprints, e2.engTicketSprint || void 0);
|
|
971
|
+
const a2 = document.getElementById("sf-eng-ticket-type");
|
|
972
|
+
return a2 && r2 && e2.engTicketProject && (updateIssueTypeOptions(a2, e2.engTicketProject), e2.engTicketIssueType ? (a2.value = e2.engTicketIssueType, a2.style.color = "#000") : a2.value && (e2.engTicketIssueType = a2.value)), e2;
|
|
973
|
+
}
|
|
974
|
+
const le = Object.freeze(Object.defineProperty({ __proto__: null, fetchIntegrationData: async function fetchIntegrationData(e2, t2) {
|
|
975
|
+
if (!re) try {
|
|
968
976
|
const n2 = await fetchEngineeringTicketPlatformIntegrations(e2, t2);
|
|
969
|
-
|
|
977
|
+
re = resolveIntegration(n2);
|
|
970
978
|
} catch (e3) {
|
|
971
|
-
console.error("Error fetching integration data:", e3),
|
|
979
|
+
console.error("Error fetching integration data:", e3), re = null;
|
|
972
980
|
}
|
|
973
|
-
}, getFieldsForProject, getIntegrationData, getProjectsForTeam, getSprintFieldId, getUsers, hasValidIntegration, populatePriorityOptions, populateSelectOptions, populateSprintOptions, refreshIntegrationData, updateFormWithIntegrationData, updateIssueTypeOptions }, Symbol.toStringTag, { value: "Module" })),
|
|
981
|
+
}, getFieldsForProject, getIntegrationData, getProjectsForTeam, getSprintFieldId, getUsers, hasValidIntegration, populatePriorityOptions, populateSelectOptions, populateSprintOptions, refreshIntegrationData, updateFormWithIntegrationData, updateIssueTypeOptions }, Symbol.toStringTag, { value: "Module" })), ce = "sf-create-issue-preference", de = "sf-create-eng-ticket-preference";
|
|
974
982
|
function getInitialState() {
|
|
975
983
|
const e2 = (function loadUserPreferences() {
|
|
976
|
-
return { createIssue:
|
|
984
|
+
return { createIssue: f && "true" === localStorage.getItem(ce), createEngTicket: f && "true" === localStorage.getItem(de) };
|
|
977
985
|
})();
|
|
978
986
|
return { mode: "lookback", description: "", occurredInThisTab: true, createIssue: e2.createIssue, issueName: "", issueDescription: "", createEngTicket: e2.createEngTicket, engTicketTeam: "", engTicketProject: "", engTicketPriority: 0, engTicketLabels: [], engTicketSprint: "", engTicketIssueType: "", engTicketCustomFields: {} };
|
|
979
987
|
}
|
|
980
|
-
let
|
|
988
|
+
let ue = getInitialState(), pe = null, fe = null, ge = null, me = false;
|
|
981
989
|
function setTimerInterval(e2) {
|
|
982
|
-
|
|
990
|
+
ge = e2;
|
|
983
991
|
}
|
|
984
992
|
function setIsRecording(e2) {
|
|
985
|
-
|
|
993
|
+
me = e2;
|
|
986
994
|
}
|
|
987
995
|
function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
|
|
988
996
|
return `
|
|
@@ -1017,9 +1025,9 @@ function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
|
|
|
1017
1025
|
</div>
|
|
1018
1026
|
`;
|
|
1019
1027
|
}
|
|
1020
|
-
const
|
|
1028
|
+
const he = { enabled: false, openModalExistingMode: { key: "e", requireCmdCtrl: false }, openModalCaptureNewMode: { key: "n", requireCmdCtrl: false }, closeModal: { key: "escape", requireCmdCtrl: false }, submitReport: { key: "enter", requireCmdCtrl: true }, startRecording: { key: "r", requireCmdCtrl: false }, stopRecording: { key: "escape", requireCmdCtrl: true } }, ye = { shortcuts: { ...he }, resolveSessionId: null, apiKey: null, backendApi: null, triageBaseUrl: "https://app.sailfishqa.com", deactivateIsolation: () => {
|
|
1021
1029
|
}, integrationData: null, showEngTicketFieldsDefault: false };
|
|
1022
|
-
let
|
|
1030
|
+
let be = null, Se = false;
|
|
1023
1031
|
function setupCustomMultiSelectListeners(e2, t2) {
|
|
1024
1032
|
const n2 = document.getElementById(`${e2}-container`), i2 = document.getElementById(`${e2}-dropdown`);
|
|
1025
1033
|
if (!n2 || !i2) return;
|
|
@@ -1042,10 +1050,10 @@ function setupCustomMultiSelectListeners(e2, t2) {
|
|
|
1042
1050
|
n3.stopPropagation();
|
|
1043
1051
|
const o3 = e4.dataset.value || "", s3 = i2.querySelector(`.sf-multiselect-option[data-value="${o3}"]`);
|
|
1044
1052
|
s3 && (s3.dataset.selected = "false", s3.style.backgroundColor = ""), updateChipsDisplay();
|
|
1045
|
-
const
|
|
1053
|
+
const r2 = [];
|
|
1046
1054
|
i2.querySelectorAll(".sf-multiselect-option").forEach((e5) => {
|
|
1047
|
-
"true" === e5.dataset.selected &&
|
|
1048
|
-
}), t2(
|
|
1055
|
+
"true" === e5.dataset.selected && r2.push(e5.dataset.value || "");
|
|
1056
|
+
}), t2(r2);
|
|
1049
1057
|
});
|
|
1050
1058
|
})), e3;
|
|
1051
1059
|
}
|
|
@@ -1070,12 +1078,12 @@ function renderDynamicFields(e2, t2) {
|
|
|
1070
1078
|
if (!i2 || 0 === i2.length) return void (n2.innerHTML = "");
|
|
1071
1079
|
const s2 = i2.map((e3) => (function renderDynamicField(e4, t3, n3 = []) {
|
|
1072
1080
|
var _a, _b, _c, _d;
|
|
1073
|
-
const i3 = e4.fieldId || e4.key, o3 = e4.name, s3 = (_a = e4.schema) == null ? void 0 : _a.type,
|
|
1074
|
-
if (d2.includes(i3) || d2.includes(
|
|
1081
|
+
const i3 = e4.fieldId || e4.key, o3 = e4.name, s3 = (_a = e4.schema) == null ? void 0 : _a.type, r2 = (_b = e4.schema) == null ? void 0 : _b.system, a2 = (_c = e4.schema) == null ? void 0 : _c.custom, l2 = e4.required || false, c2 = e4.allowedValues, d2 = ["summary", "description", "project", "issuetype", "priority"];
|
|
1082
|
+
if (d2.includes(i3) || d2.includes(r2)) return null;
|
|
1075
1083
|
const u2 = l2 ? '<span style="color:#ef4444;">*</span>' : "", p2 = "width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none;";
|
|
1076
1084
|
switch (s3) {
|
|
1077
1085
|
case "string":
|
|
1078
|
-
return
|
|
1086
|
+
return a2 && a2.includes("textarea") ? `
|
|
1079
1087
|
<div>
|
|
1080
1088
|
<label for="${i3}" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">
|
|
1081
1089
|
${o3} ${u2}
|
|
@@ -1193,7 +1201,7 @@ function renderDynamicFields(e2, t2) {
|
|
|
1193
1201
|
}
|
|
1194
1202
|
return null;
|
|
1195
1203
|
case "array":
|
|
1196
|
-
return "labels" ===
|
|
1204
|
+
return "labels" === r2 ? null : c2 && c2.length > 0 ? renderCustomMultiSelect(i3, o3, c2, Array.isArray(t3) ? t3 : [], l2) : null;
|
|
1197
1205
|
case "parent":
|
|
1198
1206
|
case "issuelink":
|
|
1199
1207
|
return `
|
|
@@ -1232,22 +1240,22 @@ function renderDynamicFields(e2, t2) {
|
|
|
1232
1240
|
</div>
|
|
1233
1241
|
` : null;
|
|
1234
1242
|
}
|
|
1235
|
-
})(e3,
|
|
1243
|
+
})(e3, ue.engTicketCustomFields[e3.fieldId || e3.key], o2)).filter(Boolean).join("");
|
|
1236
1244
|
n2.innerHTML = s2 || "", i2.forEach((e3) => {
|
|
1237
1245
|
var _a;
|
|
1238
1246
|
const t3 = e3.fieldId || e3.key, n3 = (_a = e3.schema) == null ? void 0 : _a.type, i3 = e3.allowedValues;
|
|
1239
1247
|
"array" === n3 && i3 && i3.length > 0 && setupCustomMultiSelectListeners(t3, (e4) => {
|
|
1240
|
-
|
|
1248
|
+
ue.engTicketCustomFields[t3] = e4;
|
|
1241
1249
|
});
|
|
1242
1250
|
});
|
|
1243
1251
|
}
|
|
1244
1252
|
function generateEngTicketFieldsHTML() {
|
|
1245
1253
|
var _a;
|
|
1246
|
-
const e2 =
|
|
1254
|
+
const e2 = ye.integrationData;
|
|
1247
1255
|
if (!e2) return "";
|
|
1248
1256
|
const t2 = "jira" === ((_a = e2.provider) == null ? void 0 : _a.toLowerCase());
|
|
1249
1257
|
let n2 = "<div style='display:flex; flex-direction:column; gap:12px;'>";
|
|
1250
|
-
return e2.teams && Array.isArray(e2.teams) && e2.teams.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-team" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Team\n </label>\n <select id="sf-eng-ticket-team"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select team...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-project" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Project\n </label>\n <select id="sf-eng-ticket-project"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project...</option>\n </select>\n </div>\n ', t2 && (n2 += '\n <div>\n <label for="sf-eng-ticket-type" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Issue Type\n </label>\n <select id="sf-eng-ticket-type"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project first...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-priority" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Priority\n </label>\n <select id="sf-eng-ticket-priority"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white;">\n </select>\n </div>\n ', e2.labels && Array.isArray(e2.labels) && e2.labels.length > 0 && (n2 += renderCustomMultiSelect("sf-eng-ticket-labels", "Labels", e2.labels,
|
|
1258
|
+
return e2.teams && Array.isArray(e2.teams) && e2.teams.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-team" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Team\n </label>\n <select id="sf-eng-ticket-team"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select team...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-project" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Project\n </label>\n <select id="sf-eng-ticket-project"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project...</option>\n </select>\n </div>\n ', t2 && (n2 += '\n <div>\n <label for="sf-eng-ticket-type" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Issue Type\n </label>\n <select id="sf-eng-ticket-type"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select project first...</option>\n </select>\n </div>\n '), n2 += '\n <div>\n <label for="sf-eng-ticket-priority" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Priority\n </label>\n <select id="sf-eng-ticket-priority"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white;">\n </select>\n </div>\n ', e2.labels && Array.isArray(e2.labels) && e2.labels.length > 0 && (n2 += renderCustomMultiSelect("sf-eng-ticket-labels", "Labels", e2.labels, ue.engTicketLabels, false)), t2 && e2.sprints && Array.isArray(e2.sprints) && e2.sprints.length > 0 && (n2 += '\n <div>\n <label for="sf-eng-ticket-sprint" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">\n Sprint\n </label>\n <select id="sf-eng-ticket-sprint"\n style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none; appearance:none; cursor:pointer; background-color: white; color: #9ca3af;">\n <option value="" selected style="color: #9ca3af;">Select sprint...</option>\n </select>\n </div>\n '), n2 += '\n <div id="sf-dynamic-fields-container" style="display: flex; flex-direction: column; gap: 12px;"></div>\n ', n2 += "</div>", n2;
|
|
1251
1259
|
}
|
|
1252
1260
|
function getShortcutKeyCmdCtrlLabel() {
|
|
1253
1261
|
return (function isMacPlatform() {
|
|
@@ -1261,19 +1269,19 @@ function getShortcutLabelFromContext(e2) {
|
|
|
1261
1269
|
return e3.requireCmdCtrl && t2.push(getShortcutKeyCmdCtrlLabel()), t2.push((function formatShortcutKeyLabel(e4) {
|
|
1262
1270
|
return ({ escape: "esc" }[e4.toLowerCase()] || e4).toUpperCase();
|
|
1263
1271
|
})(e3.key)), t2.map((e4) => `<span style="background: #F1F5F9; border:1px solid #cbd5e1; border-radius: 4px; padding: 0 4px; font-weight: 500; font-size: 12px; color: #94A3B8; line-height: 16px;">${e4}</span>`).join(e3.requireCmdCtrl ? " + " : "");
|
|
1264
|
-
})(
|
|
1272
|
+
})(ye.shortcuts[e2]);
|
|
1265
1273
|
}
|
|
1266
1274
|
function getSessionIdSafely() {
|
|
1267
|
-
if (!
|
|
1268
|
-
return
|
|
1275
|
+
if (!ye.resolveSessionId) throw new Error("getSessionId not defined");
|
|
1276
|
+
return ye.resolveSessionId();
|
|
1269
1277
|
}
|
|
1270
1278
|
function openReportIssueModal(e2) {
|
|
1271
|
-
|
|
1279
|
+
me ? stopRecording() : (Se = (e2 == null ? void 0 : e2.showEngTicketFields) ?? ye.showEngTicketFieldsDefault, injectModalHTML(), be && document.body.appendChild(be));
|
|
1272
1280
|
}
|
|
1273
1281
|
function closeModal() {
|
|
1274
|
-
|
|
1275
|
-
|
|
1276
|
-
})(),
|
|
1282
|
+
ye.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (be == null ? void 0 : be.parentNode) && be.parentNode.removeChild(be), be = null, me || (function resetState() {
|
|
1283
|
+
ue = getInitialState(), pe = null, fe = null;
|
|
1284
|
+
})(), ge && (clearInterval(ge), setTimerInterval(null));
|
|
1277
1285
|
}
|
|
1278
1286
|
function activateModalIsolation(e2) {
|
|
1279
1287
|
e2.setAttribute("role", "dialog"), e2.setAttribute("aria-modal", "true"), e2.hasAttribute("tabindex") || e2.setAttribute("tabindex", "-1");
|
|
@@ -1290,10 +1298,10 @@ function activateModalIsolation(e2) {
|
|
|
1290
1298
|
n3 && (e2.contains(n3) || (t3.stopImmediatePropagation(), t3.preventDefault(), refocus()));
|
|
1291
1299
|
}, o2 = ["mousedown", "mouseup", "click", "pointerdown", "pointerup", "touchstart", "touchend", "wheel", "keydown", "keyup", "focus", "focusin", "focusout", "blur"];
|
|
1292
1300
|
o2.forEach((e3) => document.addEventListener(e3, quarantine, true));
|
|
1293
|
-
let s2 = 0,
|
|
1294
|
-
const
|
|
1295
|
-
if ((e2.querySelector(":focus") ||
|
|
1296
|
-
|
|
1301
|
+
let s2 = 0, r2 = null;
|
|
1302
|
+
const a2 = t2 instanceof HTMLTextAreaElement ? t2 : null, refocus = () => {
|
|
1303
|
+
if ((e2.querySelector(":focus") || a2 || t2 || e2).focus({ preventScroll: true }), a2 && document.activeElement === a2 && r2) try {
|
|
1304
|
+
a2.setSelectionRange(r2.start, r2.end, "none");
|
|
1297
1305
|
} catch {
|
|
1298
1306
|
}
|
|
1299
1307
|
}, selectionInsideModal = () => {
|
|
@@ -1310,8 +1318,8 @@ function activateModalIsolation(e2) {
|
|
|
1310
1318
|
const watchdog = () => {
|
|
1311
1319
|
const t3 = document.activeElement, n3 = t3 === document.body || null == t3 || !e2.contains(t3), i3 = selectionInsideModal();
|
|
1312
1320
|
n3 && !i3 ? (l2 += 1, l2 >= 2 && (refocus(), l2 = 0)) : (l2 = 0, (() => {
|
|
1313
|
-
if (
|
|
1314
|
-
|
|
1321
|
+
if (a2 && document.activeElement === a2) try {
|
|
1322
|
+
r2 = { start: a2.selectionStart ?? a2.value.length, end: a2.selectionEnd ?? a2.value.length };
|
|
1315
1323
|
} catch {
|
|
1316
1324
|
}
|
|
1317
1325
|
})()), s2 = window.requestAnimationFrame(watchdog);
|
|
@@ -1332,9 +1340,9 @@ function activateModalIsolation(e2) {
|
|
|
1332
1340
|
};
|
|
1333
1341
|
}
|
|
1334
1342
|
function injectModalHTML(e2 = "lookback") {
|
|
1335
|
-
|
|
1343
|
+
be && (be.remove(), be = null), be = document.createElement("div"), be.id = "sf-report-issue-modal";
|
|
1336
1344
|
const t2 = "startnow" === e2;
|
|
1337
|
-
|
|
1345
|
+
be.innerHTML = `
|
|
1338
1346
|
<div style="position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:9998;"></div>
|
|
1339
1347
|
<div style="position:fixed; top:50%; left:50%; transform:translate(-50%, -50%);
|
|
1340
1348
|
background:#fff; border-radius:12px;
|
|
@@ -1389,7 +1397,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1389
1397
|
<textarea id="sf-issue-description" placeholder="Add description here"
|
|
1390
1398
|
style="width:100%; height:80px; padding:8px 12px; font-size:14px;
|
|
1391
1399
|
border:1px solid #cbd5e1; border-radius:6px; margin-bottom:20px;
|
|
1392
|
-
resize:none; outline:none;">${
|
|
1400
|
+
resize:none; outline:none;">${ue.description}</textarea>
|
|
1393
1401
|
|
|
1394
1402
|
<!-- When did this happen Section -->
|
|
1395
1403
|
<div id="sf-lookback-container" style="display:${t2 ? "none" : "block"}; margin-bottom:20px;">
|
|
@@ -1455,34 +1463,34 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1455
1463
|
<!-- Checkboxes on same line -->
|
|
1456
1464
|
<div style="display:flex; align-items:center; gap:24px; margin-bottom:16px;">
|
|
1457
1465
|
<label style="display:flex; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
|
|
1458
|
-
<input type="checkbox" id="sf-create-issue-checkbox" ${
|
|
1466
|
+
<input type="checkbox" id="sf-create-issue-checkbox" ${ue.createIssue ? "checked" : ""}
|
|
1459
1467
|
style="width:16px; height:16px; accent-color:#295DBF; cursor:pointer;">
|
|
1460
1468
|
Create an Issue
|
|
1461
1469
|
</label>
|
|
1462
1470
|
|
|
1463
|
-
<label id="sf-create-eng-ticket-label" style="display:${
|
|
1464
|
-
<input type="checkbox" id="sf-create-eng-ticket-checkbox" ${
|
|
1471
|
+
<label id="sf-create-eng-ticket-label" style="display:${ye.integrationData && Se ? "flex" : "none"}; align-items:center; gap:8px; font-size:14px; font-weight:500; cursor:pointer;">
|
|
1472
|
+
<input type="checkbox" id="sf-create-eng-ticket-checkbox" ${ue.createEngTicket ? "checked" : ""}
|
|
1465
1473
|
style="width:16px; height:16px; accent-color:#295DBF; cursor:pointer;">
|
|
1466
1474
|
Create an Eng Ticket
|
|
1467
1475
|
</label>
|
|
1468
1476
|
</div>
|
|
1469
1477
|
|
|
1470
1478
|
<!-- Issue Title Field (always shown when create issue is checked) -->
|
|
1471
|
-
<div id="sf-issue-fields-container" style="display:${
|
|
1479
|
+
<div id="sf-issue-fields-container" style="display:${ue.createIssue ? "block" : "none"};">
|
|
1472
1480
|
<div style="display:flex; flex-direction:column; gap:12px;">
|
|
1473
1481
|
<div>
|
|
1474
1482
|
<label for="sf-issue-name" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">
|
|
1475
1483
|
Title <span style="color:#ef4444;">*</span>
|
|
1476
1484
|
</label>
|
|
1477
1485
|
<input type="text" id="sf-issue-name" placeholder="Enter title"
|
|
1478
|
-
value="${
|
|
1486
|
+
value="${ue.issueName}"
|
|
1479
1487
|
style="width:100%; padding:8px 12px; font-size:14px; border:1px solid #cbd5e1; border-radius:6px; outline:none;">
|
|
1480
1488
|
</div>
|
|
1481
1489
|
</div>
|
|
1482
1490
|
</div>
|
|
1483
1491
|
|
|
1484
1492
|
<!-- Engineering Ticket Fields (shown when create eng ticket is checked) -->
|
|
1485
|
-
<div id="sf-eng-ticket-fields-container" style="display:${
|
|
1493
|
+
<div id="sf-eng-ticket-fields-container" style="display:${ue.createEngTicket && ye.integrationData ? "block" : "none"}; margin-top: ${ue.createIssue ? "12px" : "0"};">
|
|
1486
1494
|
${generateEngTicketFieldsHTML()}
|
|
1487
1495
|
</div>
|
|
1488
1496
|
</div>
|
|
@@ -1525,8 +1533,8 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1525
1533
|
</div>
|
|
1526
1534
|
</div>
|
|
1527
1535
|
</div>
|
|
1528
|
-
`,
|
|
1529
|
-
const e3 =
|
|
1536
|
+
`, ue.mode = e2, document.body.appendChild(be), (function bindListeners() {
|
|
1537
|
+
const e3 = be == null ? void 0 : be.querySelectorAll(".sf-issue-tab"), t3 = document.getElementById("sf-start-recording-btn"), n2 = document.getElementById("sf-modal-close-btn"), i2 = document.getElementById("sf-issue-submit-btn"), o2 = document.getElementById("sf-lookback-minutes");
|
|
1530
1538
|
e3 == null ? void 0 : e3.forEach((e4) => {
|
|
1531
1539
|
e4.addEventListener("click", (e5) => {
|
|
1532
1540
|
const t4 = e5.currentTarget.dataset.mode;
|
|
@@ -1534,9 +1542,9 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1534
1542
|
});
|
|
1535
1543
|
}), n2 && (n2.onclick = closeModal);
|
|
1536
1544
|
o2 && o2.addEventListener("change", () => {
|
|
1537
|
-
"lookback" ===
|
|
1545
|
+
"lookback" === ue.mode && (i2.disabled = false, i2.style.opacity = "1", i2.style.cursor = "pointer");
|
|
1538
1546
|
});
|
|
1539
|
-
const s2 =
|
|
1547
|
+
const s2 = be == null ? void 0 : be.querySelectorAll(".sf-collapsible-header");
|
|
1540
1548
|
s2 == null ? void 0 : s2.forEach((e4) => {
|
|
1541
1549
|
e4.addEventListener("click", (e5) => {
|
|
1542
1550
|
const t4 = e5.currentTarget, n3 = t4.dataset.target, i3 = document.getElementById(n3), o3 = t4.querySelector(".sf-chevron");
|
|
@@ -1548,20 +1556,20 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1548
1556
|
}
|
|
1549
1557
|
});
|
|
1550
1558
|
});
|
|
1551
|
-
const
|
|
1552
|
-
|
|
1553
|
-
const e4 =
|
|
1554
|
-
|
|
1559
|
+
const r2 = document.getElementById("sf-create-issue-checkbox"), a2 = document.getElementById("sf-issue-fields-container"), l2 = document.getElementById("sf-create-eng-ticket-checkbox"), c2 = document.getElementById("sf-eng-ticket-fields-container");
|
|
1560
|
+
r2 && r2.addEventListener("change", () => {
|
|
1561
|
+
const e4 = r2.checked;
|
|
1562
|
+
ue.createIssue = e4, localStorage.setItem(ce, String(e4)), a2 && (a2.style.display = e4 ? "block" : "none"), !e4 && l2 && (l2.checked = false, ue.createEngTicket = false, localStorage.setItem(de, "false"), c2 && (c2.style.display = "none"));
|
|
1555
1563
|
});
|
|
1556
1564
|
l2 && l2.addEventListener("change", async () => {
|
|
1557
1565
|
var _a;
|
|
1558
1566
|
const e4 = l2.checked;
|
|
1559
|
-
if (
|
|
1560
|
-
if (!hasValidIntegration()) return l2.checked = false,
|
|
1567
|
+
if (ue.createEngTicket = e4, localStorage.setItem(de, String(e4)), e4 && !ue.createIssue && (ue.createIssue = true, localStorage.setItem(ce, "true"), r2 && (r2.checked = true), a2 && (a2.style.display = "block")), c2 && (c2.style.display = e4 ? "block" : "none"), e4) {
|
|
1568
|
+
if (!hasValidIntegration()) return l2.checked = false, ue.createEngTicket = false, localStorage.setItem(de, "false"), c2 && (c2.style.display = "none"), void alert("No engineering ticket integration found. Please install and configure an integration (Jira, Linear, or Zendesk) first.");
|
|
1561
1569
|
const e5 = getIntegrationData();
|
|
1562
1570
|
if (e5) {
|
|
1563
|
-
if (!
|
|
1564
|
-
getFieldsForProject(
|
|
1571
|
+
if (!ue.engTicketTeam && e5.defaultTeam && (ue.engTicketTeam = e5.defaultTeam), !ue.engTicketProject && e5.defaultProject && (ue.engTicketProject = e5.defaultProject), !ue.engTicketPriority && e5.defaultPriority && (ue.engTicketPriority = e5.defaultPriority), updateFormWithIntegrationData(ue), "jira" === ((_a = e5.provider) == null ? void 0 : _a.toLowerCase()) && e5.jiraReporterAccountId && ue.engTicketProject) {
|
|
1572
|
+
getFieldsForProject(ue.engTicketProject, ue.engTicketIssueType).find((e6) => "reporter" === e6.fieldId) && !ue.engTicketCustomFields.reporter && (ue.engTicketCustomFields.reporter = e5.jiraReporterAccountId);
|
|
1565
1573
|
}
|
|
1566
1574
|
const t4 = document.getElementById("sf-eng-ticket-project"), n3 = document.getElementById("sf-eng-ticket-type");
|
|
1567
1575
|
t4 && t4.value && renderDynamicFields(t4.value, n3 == null ? void 0 : n3.value);
|
|
@@ -1570,11 +1578,11 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1570
1578
|
});
|
|
1571
1579
|
const d2 = document.getElementById("sf-issue-name");
|
|
1572
1580
|
d2 && d2.addEventListener("input", () => {
|
|
1573
|
-
|
|
1581
|
+
ue.issueName = d2.value;
|
|
1574
1582
|
});
|
|
1575
1583
|
bindEngTicketListeners(), t3 && (t3.onclick = () => {
|
|
1576
1584
|
const e4 = document.getElementById("sf-issue-description");
|
|
1577
|
-
e4 && (
|
|
1585
|
+
e4 && (ue.description = e4.value), (function startCountdownThenRecord() {
|
|
1578
1586
|
if (document.getElementById("sf-countdown-overlay")) return;
|
|
1579
1587
|
const e5 = document.createElement("div");
|
|
1580
1588
|
e5.id = "sf-countdown-overlay", e5.style.cssText = "\n position: fixed;\n inset: 0;\n background: rgba(0,0,0,0.6);\n z-index: 10001;\n display: flex;\n justify-content: center;\n align-items: center;\n font-size: 80px;\n font-weight: bold;\n color: white;\n font-family: sans-serif;\n ";
|
|
@@ -1584,10 +1592,10 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1584
1592
|
if (t4--, t4 > 0) e5.textContent = t4.toString();
|
|
1585
1593
|
else {
|
|
1586
1594
|
clearInterval(n3), document.body.removeChild(e5), (function setRecordingStartTime(e6) {
|
|
1587
|
-
|
|
1595
|
+
pe = e6;
|
|
1588
1596
|
})(Date.now()), setIsRecording(true);
|
|
1589
1597
|
try {
|
|
1590
|
-
const { enableFunctionSpanTracking: e6 } = await Promise.resolve().then(() =>
|
|
1598
|
+
const { enableFunctionSpanTracking: e6 } = await Promise.resolve().then(() => j);
|
|
1591
1599
|
e6();
|
|
1592
1600
|
} catch (e6) {
|
|
1593
1601
|
console.error("[Report Issue] Failed to enable function span tracking:", e6);
|
|
@@ -1614,7 +1622,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1614
1622
|
const t5 = e6.querySelector("#sf-recording-timer");
|
|
1615
1623
|
if (!t5) return;
|
|
1616
1624
|
const n4 = setInterval(() => {
|
|
1617
|
-
const e7 = Date.now() - (
|
|
1625
|
+
const e7 = Date.now() - (pe ?? Date.now()), n5 = Math.floor(e7 / 6e4).toString().padStart(2, "0"), i3 = Math.floor(e7 % 6e4 / 1e3).toString().padStart(2, "0");
|
|
1618
1626
|
t5.textContent = `${n5}:${i3}`;
|
|
1619
1627
|
}, 1e3);
|
|
1620
1628
|
setTimerInterval(n4);
|
|
@@ -1623,33 +1631,33 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1623
1631
|
}, 1e3);
|
|
1624
1632
|
})();
|
|
1625
1633
|
});
|
|
1626
|
-
|
|
1634
|
+
be == null ? void 0 : be.addEventListener("click", (e4) => {
|
|
1627
1635
|
var _a;
|
|
1628
1636
|
if (e4.target.closest("#sf-issue-submit-btn")) {
|
|
1629
|
-
const e5 = ((_a = document.getElementById("sf-issue-description")) == null ? void 0 : _a.value) || "", t4 =
|
|
1630
|
-
if (
|
|
1637
|
+
const e5 = ((_a = document.getElementById("sf-issue-description")) == null ? void 0 : _a.value) || "", t4 = ue.mode;
|
|
1638
|
+
if (ue.description = e5, ue.createIssue && !ue.issueName.trim()) return void alert("Issue title is required when creating an issue.");
|
|
1631
1639
|
let n3, i3;
|
|
1632
|
-
if ("startnow" === t4) n3 =
|
|
1640
|
+
if ("startnow" === t4) n3 = pe ?? Date.now() - 3e5, i3 = fe ?? Date.now();
|
|
1633
1641
|
else {
|
|
1634
1642
|
const e6 = 60 * Number((o2 == null ? void 0 : o2.value) || "2") * 1e3;
|
|
1635
1643
|
i3 = Date.now(), n3 = i3 - e6;
|
|
1636
1644
|
}
|
|
1637
|
-
if (
|
|
1638
|
-
const o3 = document.getElementById("sf-issue-name"), s3 = document.getElementById("sf-eng-ticket-team"),
|
|
1645
|
+
if (ue.createIssue) {
|
|
1646
|
+
const o3 = document.getElementById("sf-issue-name"), s3 = document.getElementById("sf-eng-ticket-team"), r3 = document.getElementById("sf-eng-ticket-project"), a3 = document.getElementById("sf-eng-ticket-priority"), l3 = document.getElementById("sf-eng-ticket-type"), c3 = (o3 == null ? void 0 : o3.value) || "", d3 = e5, u2 = (s3 == null ? void 0 : s3.value) || "", p2 = (r3 == null ? void 0 : r3.value) || "", f2 = a3 ? Number(a3.value) : 0, g2 = ue.engTicketLabels, m2 = (l3 == null ? void 0 : l3.value) || "", h2 = { ...ue.engTicketCustomFields };
|
|
1639
1647
|
document.querySelectorAll(".sf-dynamic-field").forEach((e6) => {
|
|
1640
1648
|
const t5 = e6, n4 = t5.dataset.fieldId;
|
|
1641
1649
|
n4 && ("checkbox" === t5.type ? h2[n4] = t5.checked : "number" === t5.type ? h2[n4] = parseFloat(t5.value) || null : t5.classList.contains("sf-custom-multiselect") || (h2[n4] = t5.value));
|
|
1642
1650
|
});
|
|
1643
|
-
const y2 = document.getElementById("sf-eng-ticket-sprint"), b2 = (y2 == null ? void 0 : y2.value) ||
|
|
1651
|
+
const y2 = document.getElementById("sf-eng-ticket-sprint"), b2 = (y2 == null ? void 0 : y2.value) || ue.engTicketSprint;
|
|
1644
1652
|
if (b2) {
|
|
1645
1653
|
const e6 = getSprintFieldId();
|
|
1646
1654
|
h2[e6] = parseInt(b2, 10);
|
|
1647
1655
|
}
|
|
1648
|
-
closeModal(), (async function createTriageAndIssue(e6, t5, n4, i4, o4, s4,
|
|
1656
|
+
closeModal(), (async function createTriageAndIssue(e6, t5, n4, i4, o4, s4, r4, a4, l4, c4, d4, u3, p3) {
|
|
1649
1657
|
var _a2, _b, _c;
|
|
1650
1658
|
try {
|
|
1651
1659
|
showStatusModal(true);
|
|
1652
|
-
const f3 = await createTriageAndIssueFromRecorder(
|
|
1660
|
+
const f3 = await createTriageAndIssueFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4, i4, o4, s4, r4, a4, l4, c4, d4, u3, p3);
|
|
1653
1661
|
if ((_a2 = f3 == null ? void 0 : f3.errors) == null ? void 0 : _a2.length) {
|
|
1654
1662
|
const e7 = f3.errors.map((e8) => e8.message).join("; ");
|
|
1655
1663
|
return console.error("GraphQL error creating triage and issue:", e7), void showStatusModal(false, null, e7);
|
|
@@ -1659,12 +1667,12 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1659
1667
|
} catch (e7) {
|
|
1660
1668
|
console.error("Error creating triage and issue:", e7), showStatusModal(false, null, "Something went wrong. Please try again.");
|
|
1661
1669
|
}
|
|
1662
|
-
})(`${n3}`, `${i3}`, e5, c3, d3,
|
|
1670
|
+
})(`${n3}`, `${i3}`, e5, c3, d3, ue.createEngTicket, u2, p2, f2, g2, m2, h2, "startnow" === t4 ? "RECORDED" : "LOOKBACK");
|
|
1663
1671
|
} else closeModal(), (async function createTriage(e6, t5, n4, i4) {
|
|
1664
1672
|
var _a2, _b, _c;
|
|
1665
1673
|
try {
|
|
1666
1674
|
showStatusModal(true);
|
|
1667
|
-
const o3 = await createTriageFromRecorder(
|
|
1675
|
+
const o3 = await createTriageFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4, i4);
|
|
1668
1676
|
if ((_a2 = o3 == null ? void 0 : o3.errors) == null ? void 0 : _a2.length) {
|
|
1669
1677
|
const e7 = o3.errors.map((e8) => e8.message).join("; ");
|
|
1670
1678
|
return console.error("GraphQL error creating triage:", e7), void showStatusModal(false, null, e7);
|
|
@@ -1677,13 +1685,13 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1677
1685
|
})(`${n3}`, `${i3}`, e5, "startnow" === t4 ? "RECORDED" : "LOOKBACK");
|
|
1678
1686
|
}
|
|
1679
1687
|
});
|
|
1680
|
-
})(),
|
|
1688
|
+
})(), ye.deactivateIsolation = activateModalIsolation(be), ye.integrationData && ue.createEngTicket ? initializeEngTicketForm() : ye.integrationData || (ue.createEngTicket = false), ye.apiKey && ye.backendApi && refreshIntegrationData(ye.apiKey, ye.backendApi).then((e3) => {
|
|
1681
1689
|
if (!e3 || !document.getElementById("sf-report-issue-modal")) return;
|
|
1682
|
-
|
|
1690
|
+
ye.integrationData = e3;
|
|
1683
1691
|
const t3 = document.getElementById("sf-eng-ticket-fields-container");
|
|
1684
1692
|
if (t3) {
|
|
1685
1693
|
const e4 = generateEngTicketFieldsHTML();
|
|
1686
|
-
e4 && (t3.innerHTML = e4, initializeEngTicketForm(), bindEngTicketListeners(), updateFormWithIntegrationData(
|
|
1694
|
+
e4 && (t3.innerHTML = e4, initializeEngTicketForm(), bindEngTicketListeners(), updateFormWithIntegrationData(ue), renderDynamicFields(ue.engTicketProject, ue.engTicketIssueType));
|
|
1687
1695
|
}
|
|
1688
1696
|
if (Se) {
|
|
1689
1697
|
const e4 = document.getElementById("sf-create-eng-ticket-label");
|
|
@@ -1693,37 +1701,37 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1693
1701
|
}
|
|
1694
1702
|
function initializeEngTicketForm() {
|
|
1695
1703
|
var _a;
|
|
1696
|
-
const e2 =
|
|
1704
|
+
const e2 = ye.integrationData;
|
|
1697
1705
|
if (e2) {
|
|
1698
|
-
if (!
|
|
1699
|
-
getFieldsForProject(
|
|
1706
|
+
if (!ue.engTicketTeam && e2.defaultTeam && (ue.engTicketTeam = e2.defaultTeam), !ue.engTicketProject && e2.defaultProject && (ue.engTicketProject = e2.defaultProject), !ue.engTicketPriority && e2.defaultPriority && (ue.engTicketPriority = e2.defaultPriority), updateFormWithIntegrationData(ue), "jira" === ((_a = e2.provider) == null ? void 0 : _a.toLowerCase()) && e2.jiraReporterAccountId && ue.engTicketProject) {
|
|
1707
|
+
getFieldsForProject(ue.engTicketProject, ue.engTicketIssueType).find((e3) => "reporter" === e3.fieldId) && !ue.engTicketCustomFields.reporter && (ue.engTicketCustomFields.reporter = e2.jiraReporterAccountId);
|
|
1700
1708
|
}
|
|
1701
|
-
|
|
1709
|
+
ue.engTicketProject && renderDynamicFields(ue.engTicketProject, ue.engTicketIssueType);
|
|
1702
1710
|
}
|
|
1703
1711
|
}
|
|
1704
1712
|
function setActiveTab(e2) {
|
|
1705
|
-
|
|
1706
|
-
const t2 =
|
|
1713
|
+
ue.mode = e2;
|
|
1714
|
+
const t2 = be == null ? void 0 : be.querySelector("#sf-tab-lookback"), n2 = be == null ? void 0 : be.querySelector("#sf-tab-startnow");
|
|
1707
1715
|
"lookback" === e2 ? (t2.style.background = "white", t2.style.color = "#0F172A", n2.style.background = "transparent", n2.style.color = "#64748B") : (n2.style.background = "white", n2.style.color = "#0F172A", t2.style.background = "transparent", t2.style.color = "#64748B");
|
|
1708
1716
|
}
|
|
1709
1717
|
function updateModeSpecificUI(e2) {
|
|
1710
|
-
const t2 = document.querySelector("#sf-issue-mode-info div"), n2 = document.getElementById("sf-issue-submit-btn"), i2 = document.getElementById("sf-record-button-container"), o2 = document.getElementById("sf-recording-timer-label"), s2 = document.getElementById("sf-recording-timer-display"),
|
|
1711
|
-
if (t2 && n2 && i2 && o2 && s2 &&
|
|
1712
|
-
i2.style.display = "block",
|
|
1713
|
-
const e3 = null !==
|
|
1714
|
-
if (n2.disabled = !e3, n2.style.opacity = e3 ? "1" : "0.4", n2.style.cursor = e3 ? "pointer" : "not-allowed",
|
|
1715
|
-
const e4 = Math.floor((
|
|
1718
|
+
const t2 = document.querySelector("#sf-issue-mode-info div"), n2 = document.getElementById("sf-issue-submit-btn"), i2 = document.getElementById("sf-record-button-container"), o2 = document.getElementById("sf-recording-timer-label"), s2 = document.getElementById("sf-recording-timer-display"), r2 = document.getElementById("sf-modal-footer"), a2 = document.getElementById("sf-lookback-container");
|
|
1719
|
+
if (t2 && n2 && i2 && o2 && s2 && r2 && a2) if ("startnow" === e2) {
|
|
1720
|
+
i2.style.display = "block", a2.style.display = "none", r2.style.justifyContent = "space-between", t2.textContent = "I want to reproduce the issue right now.";
|
|
1721
|
+
const e3 = null !== pe && null !== fe;
|
|
1722
|
+
if (n2.disabled = !e3, n2.style.opacity = e3 ? "1" : "0.4", n2.style.cursor = e3 ? "pointer" : "not-allowed", pe && fe) {
|
|
1723
|
+
const e4 = Math.floor((fe - pe) / 1e3), t3 = String(Math.floor(e4 / 60)).padStart(2, "0"), n3 = String(e4 % 60).padStart(2, "0");
|
|
1716
1724
|
o2.style.display = "block", s2.textContent = `${t3}:${n3}`;
|
|
1717
1725
|
} else o2.style.display = "none";
|
|
1718
|
-
} else i2.style.display = "none", o2.style.display = "none",
|
|
1726
|
+
} else i2.style.display = "none", o2.style.display = "none", a2.style.display = "block", r2.style.justifyContent = "flex-end", t2.textContent = "Something already happened. Capture the past few minutes.", n2.disabled = false, n2.style.opacity = "1", n2.style.cursor = "pointer";
|
|
1719
1727
|
}
|
|
1720
1728
|
function bindEngTicketListeners() {
|
|
1721
1729
|
const e2 = document.getElementById("sf-eng-ticket-team"), t2 = document.getElementById("sf-eng-ticket-project"), n2 = document.getElementById("sf-eng-ticket-priority"), i2 = document.getElementById("sf-eng-ticket-labels-container"), o2 = document.getElementById("sf-eng-ticket-type"), s2 = document.getElementById("sf-eng-ticket-sprint");
|
|
1722
1730
|
e2 && e2.addEventListener("change", () => {
|
|
1723
|
-
|
|
1731
|
+
ue.engTicketTeam = e2.value, e2.style.color = e2.value ? "" : "#9ca3af";
|
|
1724
1732
|
const t3 = document.getElementById("sf-eng-ticket-project");
|
|
1725
1733
|
if (t3) {
|
|
1726
|
-
|
|
1734
|
+
ue.engTicketProject = "", ue.engTicketCustomFields = {};
|
|
1727
1735
|
const n3 = getProjectsForTeam(e2.value);
|
|
1728
1736
|
t3.innerHTML = '<option value="">Select project...</option>', n3.forEach((e3) => {
|
|
1729
1737
|
const n4 = document.createElement("option");
|
|
@@ -1732,38 +1740,38 @@ function bindEngTicketListeners() {
|
|
|
1732
1740
|
}
|
|
1733
1741
|
}), t2 && t2.addEventListener("change", () => {
|
|
1734
1742
|
var _a;
|
|
1735
|
-
|
|
1743
|
+
ue.engTicketProject = t2.value, t2.style.color = t2.value ? "" : "#9ca3af", ue.engTicketCustomFields = {};
|
|
1736
1744
|
const e3 = getIntegrationData();
|
|
1737
|
-
if (e3 && o2 && (updateIssueTypeOptions(o2, t2.value),
|
|
1738
|
-
getFieldsForProject(t2.value,
|
|
1745
|
+
if (e3 && o2 && (updateIssueTypeOptions(o2, t2.value), ue.engTicketIssueType = o2.value), e3 && "jira" === ((_a = e3.provider) == null ? void 0 : _a.toLowerCase()) && e3.jiraReporterAccountId && t2.value) {
|
|
1746
|
+
getFieldsForProject(t2.value, ue.engTicketIssueType).find((e4) => "reporter" === e4.fieldId) && (ue.engTicketCustomFields.reporter = e3.jiraReporterAccountId);
|
|
1739
1747
|
}
|
|
1740
|
-
renderDynamicFields(t2.value,
|
|
1748
|
+
renderDynamicFields(t2.value, ue.engTicketIssueType);
|
|
1741
1749
|
}), s2 && s2.addEventListener("change", () => {
|
|
1742
|
-
|
|
1750
|
+
ue.engTicketSprint = s2.value, s2.style.color = s2.value ? "" : "#9ca3af";
|
|
1743
1751
|
}), n2 && n2.addEventListener("change", () => {
|
|
1744
|
-
|
|
1752
|
+
ue.engTicketPriority = Number(n2.value);
|
|
1745
1753
|
}), i2 && setupCustomMultiSelectListeners("sf-eng-ticket-labels", (e3) => {
|
|
1746
|
-
|
|
1754
|
+
ue.engTicketLabels = e3;
|
|
1747
1755
|
}), o2 && o2.addEventListener("change", () => {
|
|
1748
|
-
|
|
1756
|
+
ue.engTicketIssueType = o2.value, o2.style.color = o2.value ? "" : "#9ca3af";
|
|
1749
1757
|
const e3 = document.getElementById("sf-eng-ticket-project");
|
|
1750
1758
|
if (e3 && e3.value) {
|
|
1751
|
-
const t3 =
|
|
1752
|
-
|
|
1759
|
+
const t3 = ue.engTicketCustomFields.reporter;
|
|
1760
|
+
ue.engTicketCustomFields = {}, t3 && (ue.engTicketCustomFields.reporter = t3), renderDynamicFields(e3.value, o2.value);
|
|
1753
1761
|
}
|
|
1754
1762
|
});
|
|
1755
|
-
const
|
|
1756
|
-
|
|
1763
|
+
const r2 = document.getElementById("sf-dynamic-fields-container");
|
|
1764
|
+
r2 && (r2.addEventListener("input", (e3) => {
|
|
1757
1765
|
const t3 = e3.target;
|
|
1758
1766
|
if (t3.classList.contains("sf-dynamic-field")) {
|
|
1759
1767
|
const e4 = t3.dataset.fieldId;
|
|
1760
|
-
e4 && ("checkbox" === t3.type ?
|
|
1768
|
+
e4 && ("checkbox" === t3.type ? ue.engTicketCustomFields[e4] = t3.checked : "number" === t3.type ? ue.engTicketCustomFields[e4] = parseFloat(t3.value) || null : ue.engTicketCustomFields[e4] = t3.value);
|
|
1761
1769
|
}
|
|
1762
|
-
}),
|
|
1770
|
+
}), r2.addEventListener("change", (e3) => {
|
|
1763
1771
|
const t3 = e3.target;
|
|
1764
1772
|
if (t3.classList.contains("sf-dynamic-field")) {
|
|
1765
1773
|
const e4 = t3.dataset.fieldId;
|
|
1766
|
-
if (e4 && (
|
|
1774
|
+
if (e4 && (ue.engTicketCustomFields[e4] = t3.value), "SELECT" === t3.tagName) {
|
|
1767
1775
|
const e5 = t3;
|
|
1768
1776
|
e5.style.color = e5.value ? "" : "#9ca3af";
|
|
1769
1777
|
}
|
|
@@ -1773,10 +1781,10 @@ function bindEngTicketListeners() {
|
|
|
1773
1781
|
async function stopRecording() {
|
|
1774
1782
|
var _a;
|
|
1775
1783
|
!(function setRecordingEndTime(e2) {
|
|
1776
|
-
|
|
1777
|
-
})(Date.now()), setIsRecording(false),
|
|
1784
|
+
fe = e2;
|
|
1785
|
+
})(Date.now()), setIsRecording(false), ge && (clearInterval(ge), setTimerInterval(null)), (_a = document.getElementById("sf-recording-indicator")) == null ? void 0 : _a.remove();
|
|
1778
1786
|
try {
|
|
1779
|
-
const { disableFunctionSpanTracking: e2 } = await Promise.resolve().then(() =>
|
|
1787
|
+
const { disableFunctionSpanTracking: e2 } = await Promise.resolve().then(() => j);
|
|
1780
1788
|
e2();
|
|
1781
1789
|
} catch (e2) {
|
|
1782
1790
|
console.error("[Report Issue] Failed to disable function span tracking:", e2);
|
|
@@ -1789,21 +1797,21 @@ async function stopRecording() {
|
|
|
1789
1797
|
t3 && (t3.textContent = "Re-record");
|
|
1790
1798
|
}
|
|
1791
1799
|
const t2 = document.getElementById("sf-recording-timer-label"), n2 = document.getElementById("sf-recording-timer-display");
|
|
1792
|
-
if (t2 && n2 &&
|
|
1793
|
-
const e3 = Math.floor((
|
|
1800
|
+
if (t2 && n2 && pe && fe) {
|
|
1801
|
+
const e3 = Math.floor((fe - pe) / 1e3), i3 = Math.floor(e3 / 60).toString().padStart(2, "0"), o3 = (e3 % 60).toString().padStart(2, "0");
|
|
1794
1802
|
n2.textContent = `${i3}:${o3}`, t2.style.display = "block";
|
|
1795
1803
|
}
|
|
1796
1804
|
const i2 = document.getElementById("sf-issue-description");
|
|
1797
|
-
i2 && (i2.value =
|
|
1805
|
+
i2 && (i2.value = ue.description);
|
|
1798
1806
|
const o2 = document.querySelector('input[value="startnow"]');
|
|
1799
1807
|
o2 && (o2.checked = true);
|
|
1800
|
-
const s2 = document.getElementById("sf-inline-record-chip"),
|
|
1801
|
-
if (s2 &&
|
|
1802
|
-
const e3 = Math.floor(((
|
|
1803
|
-
|
|
1808
|
+
const s2 = document.getElementById("sf-inline-record-chip"), r2 = document.getElementById("sf-inline-record-timer");
|
|
1809
|
+
if (s2 && r2) {
|
|
1810
|
+
const e3 = Math.floor(((fe ?? 0) - (pe ?? 0)) / 1e3), t3 = Math.floor(e3 / 60).toString().padStart(2, "0"), n3 = Math.floor(e3 % 60).toString().padStart(2, "0");
|
|
1811
|
+
r2.textContent = `${t3}:${n3}`, r2.style.color = "black", s2.style.display = "flex";
|
|
1804
1812
|
}
|
|
1805
|
-
const
|
|
1806
|
-
|
|
1813
|
+
const a2 = document.getElementById("sf-issue-submit-btn");
|
|
1814
|
+
a2.disabled = false, a2.style.opacity = "1", a2.style.cursor = "pointer";
|
|
1807
1815
|
})();
|
|
1808
1816
|
}
|
|
1809
1817
|
function showStatusModal(e2, t2, n2) {
|
|
@@ -1813,10 +1821,10 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1813
1821
|
var _a2, _b;
|
|
1814
1822
|
(_a2 = document.getElementById("sf-report-issue-modal")) == null ? void 0 : _a2.remove(), (_b = document.getElementById("sf-triage-status-modal")) == null ? void 0 : _b.remove();
|
|
1815
1823
|
})();
|
|
1816
|
-
const o2 = !e3 && i2, s2 = n3 ? `${
|
|
1817
|
-
|
|
1818
|
-
const
|
|
1819
|
-
|
|
1824
|
+
const o2 = !e3 && i2, s2 = n3 ? `${ye.triageBaseUrl}/issues/${n3}?from=inAppReportIssue` : t3 ? `${ye.triageBaseUrl}/triage/${t3}?from=inAppReportIssue` : "", r2 = document.createElement("div");
|
|
1825
|
+
r2.id = "sf-triage-status-modal", Object.assign(r2.style, { position: "fixed", inset: "0", zIndex: "9998", display: "flex", alignItems: "center", justifyContent: "center" });
|
|
1826
|
+
const a2 = e3 ? "Reporting Issue..." : o2 ? "Failed to report issue" : "Issue reported!", l2 = e3 ? '<p style="font-size:14px; color:#64748b; line-height:20px;">This may take ~10 seconds</p>' : o2 ? `<p style="font-size:14px; color:#ef4444; line-height:20px;">${i2}</p>` : "", c2 = e3 ? '<div style="display:flex; justify-content:center; align-items:center; padding: 40px 0;">\n <div style="width:24px; height:24px; border:2px solid #295dbf; border-top:2px solid white; border-radius:50%; animation:spin 1s linear infinite;"></div>\n </div>' : "", d2 = e3 ? "" : '<div id="sf-copied-status" style="display:none; font-size:12px; font-weight:500; color:white;\n background-color:#22c55e; padding:4px 8px; border-radius:6px; white-space:nowrap; align-items:center; gap:6px;">\n <svg width="16" height="16" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg">\n <path fill-rule="evenodd" clip-rule="evenodd" d="M21 7.5L9 19.5L3 13.5L5.25 11.25L9 15L18.75 5.25L21 7.5Z" fill="white"/>\n </svg>\n Copied\n </div>';
|
|
1827
|
+
r2.innerHTML = `
|
|
1820
1828
|
<div style="position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:9998;"></div>
|
|
1821
1829
|
<div id="sf-triage-card"
|
|
1822
1830
|
style="position:relative; background:#fff; padding:24px; border-radius:12px; width:300px; max-width:90%;
|
|
@@ -1832,7 +1840,7 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1832
1840
|
</svg>
|
|
1833
1841
|
</button>
|
|
1834
1842
|
|
|
1835
|
-
<h2 style="font-size:18px; font-weight:600; margin-bottom:${e3 || o2 ? 8 : 40}px; line-height:28px;">${
|
|
1843
|
+
<h2 style="font-size:18px; font-weight:600; margin-bottom:${e3 || o2 ? 8 : 40}px; line-height:28px;">${a2}</h2>
|
|
1836
1844
|
${l2}
|
|
1837
1845
|
${c2}
|
|
1838
1846
|
|
|
@@ -1857,10 +1865,10 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1857
1865
|
<style>
|
|
1858
1866
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
1859
1867
|
</style>
|
|
1860
|
-
`, document.body.appendChild(
|
|
1861
|
-
const u2 =
|
|
1868
|
+
`, document.body.appendChild(r2);
|
|
1869
|
+
const u2 = r2.querySelector("#sf-triage-card");
|
|
1862
1870
|
(_a = document.getElementById("sf-triage-modal-close")) == null ? void 0 : _a.addEventListener("click", () => {
|
|
1863
|
-
fadeCardAndRemove(
|
|
1871
|
+
fadeCardAndRemove(r2, u2, 300);
|
|
1864
1872
|
});
|
|
1865
1873
|
const p2 = document.getElementById("sf-copy-triage-link"), f2 = document.getElementById("sf-view-triage-btn");
|
|
1866
1874
|
e3 ? (p2.disabled = true, p2.style.opacity = "0.4", p2.style.cursor = "not-allowed", f2.disabled = true, f2.style.opacity = "0.4", f2.style.cursor = "not-allowed") : (p2.disabled = false, p2.addEventListener("click", () => {
|
|
@@ -1870,15 +1878,15 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1870
1878
|
});
|
|
1871
1879
|
}), f2.disabled = false, f2.addEventListener("click", () => {
|
|
1872
1880
|
(t3 || n3) && window.open(s2, "_blank");
|
|
1873
|
-
}), o2 || setTimeout(() => fadeCardAndRemove(
|
|
1881
|
+
}), o2 || setTimeout(() => fadeCardAndRemove(r2, u2, 300), 1e4));
|
|
1874
1882
|
})(e2, "triage" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, "issue" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, n2);
|
|
1875
1883
|
}
|
|
1876
1884
|
function fadeCardAndRemove(e2, t2, n2 = 300) {
|
|
1877
1885
|
t2.style.opacity = "0", t2.addEventListener("transitionend", () => e2.remove(), { once: true }), setTimeout(() => e2.remove(), n2 + 100);
|
|
1878
1886
|
}
|
|
1879
|
-
const
|
|
1880
|
-
|
|
1881
|
-
const t3 = { ...
|
|
1887
|
+
const ve = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueContext: ye, openReportIssueModal, setupIssueReporting: function setupIssueReporting(e2) {
|
|
1888
|
+
ye.apiKey = e2.apiKey, ye.backendApi = e2.backendApi, ye.resolveSessionId = e2.getSessionId, ye.integrationData = e2.integrationData || null, ye.showEngTicketFieldsDefault = e2.showEngTicketFieldsInReportIssueModalDefault ?? false, e2.customBaseUrl && (ye.triageBaseUrl = e2.customBaseUrl), ye.shortcuts = (function mergeShortcutsConfig(e3) {
|
|
1889
|
+
const t3 = { ...he };
|
|
1882
1890
|
if (!e3) return t3;
|
|
1883
1891
|
"boolean" == typeof e3.enabled && (t3.enabled = e3.enabled);
|
|
1884
1892
|
const n2 = ["openModalExistingMode", "openModalCaptureNewMode", "closeModal", "submitReport", "startRecording", "stopRecording"];
|
|
@@ -1888,36 +1896,36 @@ const ke = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueCon
|
|
|
1888
1896
|
}
|
|
1889
1897
|
return t3;
|
|
1890
1898
|
})(e2.shortcuts);
|
|
1891
|
-
const { shortcuts: t2 } =
|
|
1899
|
+
const { shortcuts: t2 } = ye;
|
|
1892
1900
|
window.addEventListener("keydown", (e3) => {
|
|
1893
1901
|
const n2 = (function isTypingInInput() {
|
|
1894
1902
|
const e4 = document.activeElement;
|
|
1895
1903
|
return e4 instanceof HTMLInputElement || e4 instanceof HTMLTextAreaElement || e4 instanceof HTMLElement && e4.isContentEditable;
|
|
1896
|
-
})(), i2 = e3.key.toLowerCase(), o2 = e3.metaKey || e3.ctrlKey, s2 = !!document.getElementById("sf-report-issue-modal"),
|
|
1904
|
+
})(), i2 = e3.key.toLowerCase(), o2 = e3.metaKey || e3.ctrlKey, s2 = !!document.getElementById("sf-report-issue-modal"), r2 = !n2 && (t2.enabled || s2), shortcutUsed = (e4) => i2 === t2[e4].key && o2 === t2[e4].requireCmdCtrl, a2 = s2 ? (e4) => {
|
|
1897
1905
|
setActiveTab(e4), updateModeSpecificUI(e4);
|
|
1898
1906
|
} : injectModalHTML;
|
|
1899
|
-
if (
|
|
1900
|
-
if (
|
|
1901
|
-
if (s2 && !
|
|
1907
|
+
if (r2 && shortcutUsed("openModalExistingMode")) return e3.preventDefault(), void a2("lookback");
|
|
1908
|
+
if (r2 && shortcutUsed("openModalCaptureNewMode")) return e3.preventDefault(), void a2("startnow");
|
|
1909
|
+
if (s2 && !me && shortcutUsed("closeModal")) return e3.preventDefault(), void closeModal();
|
|
1902
1910
|
if (s2 && shortcutUsed("submitReport")) {
|
|
1903
1911
|
const t3 = document.getElementById("sf-issue-submit-btn");
|
|
1904
1912
|
return void (t3 && !t3.disabled && (e3.preventDefault(), t3.click()));
|
|
1905
1913
|
}
|
|
1906
|
-
if (
|
|
1907
|
-
if (s2 && "startnow" ===
|
|
1914
|
+
if (me && i2 === t2.stopRecording.key && o2 === t2.stopRecording.requireCmdCtrl) return e3.preventDefault(), void stopRecording();
|
|
1915
|
+
if (s2 && "startnow" === ue.mode && i2 === t2.startRecording.key && o2 === t2.startRecording.requireCmdCtrl && !n2) {
|
|
1908
1916
|
const t3 = document.getElementById("sf-start-recording-btn");
|
|
1909
1917
|
return void (t3 && (e3.preventDefault(), t3.click()));
|
|
1910
1918
|
}
|
|
1911
1919
|
});
|
|
1912
|
-
} }, Symbol.toStringTag, { value: "Module" })),
|
|
1920
|
+
} }, Symbol.toStringTag, { value: "Module" })), we = readDebugFlag(), ke = /* @__PURE__ */ new Map();
|
|
1913
1921
|
function getCachedRegex(e2, t2) {
|
|
1914
1922
|
const n2 = `${e2}|${t2}`;
|
|
1915
|
-
let i2 =
|
|
1916
|
-
return i2 || (i2 = new RegExp(e2, t2),
|
|
1923
|
+
let i2 = ke.get(n2);
|
|
1924
|
+
return i2 || (i2 = new RegExp(e2, t2), ke.set(n2, i2)), i2;
|
|
1917
1925
|
}
|
|
1918
|
-
const
|
|
1926
|
+
const xe = new Set([".js", ".mjs", ".cjs", ".ts", ".css", ".scss", ".sass", ".less", ".styl", ".stylus", ".png", ".jpg", ".jpeg", ".gif", ".svg", ".webp", ".avif", ".bmp", ".ico", ".tiff", ".tif", ".heic", ".woff", ".woff2", ".ttf", ".otf", ".eot", ".mp4", ".webm", ".ogv", ".mp3", ".wav", ".flac", ".pdf", ".doc", ".docx", ".xls", ".xlsx", ".ppt", ".pptx", ".csv", ".json", ".xml", ".txt", ".zip", ".rar", ".gz", ".tar", ".7z", ".map", ".webmanifest"].map((e2) => e2.toLowerCase())), Ie = ["t.co", "*.twitter.com", "*.gravatar.com", "*.googleapis.com", "*.amazonaws.com", "*.smooch.io", "*.zendesk.com", "*.zdassets.com"], Te = [400, 403], Ee = "CORS", Ce = "authorization", $e = "Authorization", Fe = { recordCanvas: false, recordCrossOriginIframes: false, collectFonts: false, inlineImages: false, recordPassword: false, recordRealName: true, recordCreditCardInfo: false, recordSsn: false, recordDob: false, sampling: {}, enableFiberTracking: false }, Le = { level: ["info", "log", "warn", "error"], lengthThreshold: 1e4, stringifyOptions: { stringLengthLimit: 1e3, numOfKeysLimit: 20, depthOfLimit: 4 }, logger: "console" };
|
|
1919
1927
|
function maskAuthorizationHeader(e2) {
|
|
1920
|
-
const t2 = e2[
|
|
1928
|
+
const t2 = e2[Ce] ? Ce : e2[$e] ? $e : null;
|
|
1921
1929
|
if (!t2) return;
|
|
1922
1930
|
const n2 = e2[t2], i2 = n2.indexOf(" ");
|
|
1923
1931
|
if (-1 !== i2) {
|
|
@@ -1948,14 +1956,14 @@ function trackDomainChangesOnce() {
|
|
|
1948
1956
|
function sendUserDeviceUuid() {
|
|
1949
1957
|
sendMessage({ type: "userDeviceUuid", userDeviceUuid: (function getOrSetUserDeviceUuid() {
|
|
1950
1958
|
let e2 = null;
|
|
1951
|
-
if (
|
|
1959
|
+
if (f) try {
|
|
1952
1960
|
e2 = localStorage.getItem("sailfishUserDeviceUuid");
|
|
1953
1961
|
} catch {
|
|
1954
1962
|
}
|
|
1955
1963
|
if (!e2) {
|
|
1956
1964
|
e2 = uuidv4();
|
|
1957
1965
|
try {
|
|
1958
|
-
|
|
1966
|
+
f && localStorage.setItem("sailfishUserDeviceUuid", e2);
|
|
1959
1967
|
} catch {
|
|
1960
1968
|
}
|
|
1961
1969
|
}
|
|
@@ -1966,24 +1974,24 @@ function handleVisibilityChange() {
|
|
|
1966
1974
|
const e2 = document.visibilityState, t2 = Date.now();
|
|
1967
1975
|
"visible" === e2 && getOrSetSessionId();
|
|
1968
1976
|
try {
|
|
1969
|
-
sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: t2, ...getUrlAndStoredUuids() } }),
|
|
1977
|
+
sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: t2, ...getUrlAndStoredUuids() } }), we && console.log(`[Sailfish] Tab became ${e2}, sent visibility change event`);
|
|
1970
1978
|
} catch (e3) {
|
|
1971
1979
|
console.warn("[Sailfish] Failed to send visibility change event:", e3);
|
|
1972
1980
|
}
|
|
1973
1981
|
sessionStorage.setItem("tabVisibilityChanged", t2.toString()), sessionStorage.setItem("tabVisibilityState", e2), invalidateUrlCache();
|
|
1974
1982
|
}
|
|
1975
1983
|
function clearPageVisitDataFromSessionStorage() {
|
|
1976
|
-
|
|
1984
|
+
g && (sessionStorage.removeItem("pageVisitUUID"), sessionStorage.removeItem("prevPageVisitUUID"), sessionStorage.removeItem("tabVisibilityChanged"), sessionStorage.removeItem("tabVisibilityState"), invalidateUrlCache());
|
|
1977
1985
|
}
|
|
1978
|
-
let
|
|
1986
|
+
let Me = false;
|
|
1979
1987
|
function _ensureModuleSideEffects() {
|
|
1980
|
-
|
|
1981
|
-
|
|
1982
|
-
window.name =
|
|
1988
|
+
Me || (Me = true, restoreFuncSpanState(), (function ensureSessionListeners() {
|
|
1989
|
+
b || (b = true, u && window.addEventListener("beforeunload", () => {
|
|
1990
|
+
window.name = h + window.name;
|
|
1983
1991
|
}));
|
|
1984
|
-
})(),
|
|
1992
|
+
})(), u && (sendUserDeviceUuid(), (function sendTimeZone() {
|
|
1985
1993
|
sendMessage({ type: "timeZone", timezone: Intl.DateTimeFormat().resolvedOptions().timeZone });
|
|
1986
|
-
})()),
|
|
1994
|
+
})()), p && document.addEventListener("visibilitychange", handleVisibilityChange), u && window.addEventListener("beforeunload", () => {
|
|
1987
1995
|
clearPageVisitDataFromSessionStorage();
|
|
1988
1996
|
}));
|
|
1989
1997
|
}
|
|
@@ -1996,15 +2004,15 @@ function matchUrlWithWildcard(e2, t2) {
|
|
|
1996
2004
|
} catch {
|
|
1997
2005
|
return false;
|
|
1998
2006
|
}
|
|
1999
|
-
const { hostname: o2, pathname: s2, port:
|
|
2000
|
-
if (!/^https?:$/.test(
|
|
2007
|
+
const { hostname: o2, pathname: s2, port: r2, protocol: a2 } = i2;
|
|
2008
|
+
if (!/^https?:$/.test(a2)) return false;
|
|
2001
2009
|
const l2 = o2.startsWith("www.") ? o2.slice(4).toLowerCase() : o2.toLowerCase();
|
|
2002
2010
|
return t2.some((e3) => {
|
|
2003
2011
|
const t3 = String(e3 || "").replace(/^[a-zA-Z]+:\/\//, "");
|
|
2004
2012
|
let [n3, i3] = t3.split("/", 2), o3 = "";
|
|
2005
2013
|
n3.includes(":") && ([n3, o3] = n3.split(":"));
|
|
2006
|
-
const
|
|
2007
|
-
if (o3 &&
|
|
2014
|
+
const a3 = getCachedRegex(`^${n3.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`, "i"), c2 = l2.startsWith("www.") ? l2.slice(4) : l2;
|
|
2015
|
+
if (o3 && "*" !== o3 && r2 !== o3) return false;
|
|
2008
2016
|
if (n3.startsWith("*.")) {
|
|
2009
2017
|
const e4 = n3.slice(2).toLowerCase();
|
|
2010
2018
|
if (!(l2 === e4 || c2 === e4 || l2.endsWith("." + e4))) return false;
|
|
@@ -2013,41 +2021,41 @@ function matchUrlWithWildcard(e2, t2) {
|
|
|
2013
2021
|
}
|
|
2014
2022
|
return true;
|
|
2015
2023
|
}
|
|
2016
|
-
if (!
|
|
2024
|
+
if (!a3.test(c2) && !a3.test(l2)) return false;
|
|
2017
2025
|
if (i3) {
|
|
2018
2026
|
return getCachedRegex(`^/${i3.replace(/\*/g, ".*").replace(/\/$/, "")}`, "i").test(s2);
|
|
2019
2027
|
}
|
|
2020
2028
|
return true;
|
|
2021
2029
|
});
|
|
2022
2030
|
}
|
|
2023
|
-
function createSkipHeadersPropagationChecker(e2 = []) {
|
|
2024
|
-
const
|
|
2031
|
+
function createSkipHeadersPropagationChecker(e2 = [], t2 = []) {
|
|
2032
|
+
const n2 = [...Ie, ...e2], i2 = t2.length > 0;
|
|
2025
2033
|
return function shouldSkipHeadersPropagation(e3) {
|
|
2026
|
-
let
|
|
2034
|
+
let o2;
|
|
2027
2035
|
try {
|
|
2028
|
-
|
|
2036
|
+
o2 = new URL("string" == typeof e3 ? e3 : String((e3 == null ? void 0 : e3.url) ?? e3), window.location.href);
|
|
2029
2037
|
} catch {
|
|
2030
2038
|
return true;
|
|
2031
2039
|
}
|
|
2032
|
-
const
|
|
2033
|
-
return !(-1 ===
|
|
2040
|
+
const s2 = o2.pathname.toLowerCase(), r2 = s2.lastIndexOf(".");
|
|
2041
|
+
return !(-1 === r2 || !xe.has(s2.slice(r2))) || (!(!i2 || matchUrlWithWildcard(e3, t2)) || !!matchUrlWithWildcard(e3, n2));
|
|
2034
2042
|
};
|
|
2035
2043
|
}
|
|
2036
|
-
function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
|
|
2037
|
-
const
|
|
2038
|
-
window.fetch = new Proxy(
|
|
2039
|
-
let c2, d2 =
|
|
2044
|
+
function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i2 = []) {
|
|
2045
|
+
const o2 = window.fetch, s2 = getOrSetSessionId(), r2 = createSkipHeadersPropagationChecker(e2, i2), a2 = ["text/event-stream", "application/x-ndjson", "application/stream+json", "application/grpc", "application/grpc-web"], l2 = ["application/octet-stream"];
|
|
2046
|
+
window.fetch = new Proxy(o2, { apply: async (e3, i3, o3) => {
|
|
2047
|
+
let c2, d2 = o3[0], u2 = o3[1] || {};
|
|
2040
2048
|
if ("string" == typeof d2) c2 = d2;
|
|
2041
2049
|
else if (d2 instanceof Request) c2 = d2.url;
|
|
2042
2050
|
else {
|
|
2043
|
-
if (!(d2 instanceof URL)) return e3.apply(i3,
|
|
2051
|
+
if (!(d2 instanceof URL)) return e3.apply(i3, o3);
|
|
2044
2052
|
c2 = d2.href;
|
|
2045
2053
|
}
|
|
2046
|
-
return
|
|
2054
|
+
return r2(c2) ? e3.apply(i3, o3) : (async function injectHeaderWrapper(e4, i4, o4, s3, r3, c3, d3) {
|
|
2047
2055
|
var _a, _b;
|
|
2048
|
-
if (!c3) return e4.apply(i4,
|
|
2056
|
+
if (!c3) return e4.apply(i4, o4);
|
|
2049
2057
|
let u3 = uuidv4();
|
|
2050
|
-
const p2 = getUrlAndStoredUuids(), f2 =
|
|
2058
|
+
const p2 = getUrlAndStoredUuids(), f2 = r3.method || "GET", g2 = Date.now();
|
|
2051
2059
|
let m2, h2 = {}, y2 = null;
|
|
2052
2060
|
try {
|
|
2053
2061
|
if (s3 instanceof Request) {
|
|
@@ -2059,63 +2067,63 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2059
2067
|
} catch (e5) {
|
|
2060
2068
|
y2 = null;
|
|
2061
2069
|
}
|
|
2062
|
-
} else
|
|
2070
|
+
} else r3.headers && (r3.headers instanceof Headers ? r3.headers.forEach((e5, t3) => {
|
|
2063
2071
|
h2[t3] = e5;
|
|
2064
|
-
}) : Array.isArray(
|
|
2072
|
+
}) : Array.isArray(r3.headers) ? r3.headers.forEach(([e5, t3]) => {
|
|
2065
2073
|
h2[e5] = t3;
|
|
2066
|
-
}) : h2 = { ...
|
|
2074
|
+
}) : h2 = { ...r3.headers }), m2 = r3.body;
|
|
2067
2075
|
} catch (e5) {
|
|
2068
|
-
|
|
2076
|
+
we && console.warn("[Sailfish] Failed to capture request data:", e5);
|
|
2069
2077
|
}
|
|
2070
2078
|
delete h2[n];
|
|
2071
2079
|
const b2 = getFuncSpanHeader();
|
|
2072
2080
|
b2 && delete h2[b2.name];
|
|
2073
|
-
const
|
|
2074
|
-
h2[n] =
|
|
2081
|
+
const S2 = `${c3}/${p2.page_visit_uuid}/${u3}`;
|
|
2082
|
+
h2[n] = S2, b2 && (h2[b2.name] = b2.value);
|
|
2075
2083
|
maskAuthorizationHeader(h2);
|
|
2076
2084
|
try {
|
|
2077
|
-
let b3 = await (async function injectHeader(e5, t3, i5,
|
|
2078
|
-
const
|
|
2085
|
+
let b3 = await (async function injectHeader(e5, t3, i5, o5, s4, r4, a3) {
|
|
2086
|
+
const l3 = getFuncSpanHeader();
|
|
2079
2087
|
if (i5 instanceof Request) {
|
|
2080
2088
|
const c4 = i5.clone(), d4 = new Headers(c4.headers);
|
|
2081
|
-
d4.set(n, `${s4}/${
|
|
2089
|
+
d4.set(n, `${s4}/${r4}/${a3}`), l3 && (d4.set(l3.name, l3.value), we && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l3.name }));
|
|
2082
2090
|
const u4 = new Request(c4, { headers: d4 });
|
|
2083
|
-
return await e5.call(t3, u4,
|
|
2091
|
+
return await e5.call(t3, u4, o5);
|
|
2084
2092
|
}
|
|
2085
2093
|
{
|
|
2086
|
-
const c4 = { ...
|
|
2087
|
-
return d4.set(n, `${s4}/${
|
|
2094
|
+
const c4 = { ...o5 }, d4 = new Headers(o5.headers || {});
|
|
2095
|
+
return d4.set(n, `${s4}/${r4}/${a3}`), l3 && (d4.set(l3.name, l3.value), we && console.log("[Sailfish] Added funcspan header to HTTP fetch:", { url: "string" == typeof i5 ? i5 : i5.href, header: l3.name })), c4.headers = d4, await e5.call(t3, i5, c4);
|
|
2088
2096
|
}
|
|
2089
|
-
})(e4, i4, s3,
|
|
2090
|
-
|
|
2097
|
+
})(e4, i4, s3, r3, c3, p2.page_visit_uuid, u3), S3 = false;
|
|
2098
|
+
Te.includes(b3.status) && (we && console.log("Perform retry as status was fail:", b3), delete h2[n], b3 = await (async function retryWithoutPropagateHeaders(e5, t3, i5, o5) {
|
|
2091
2099
|
try {
|
|
2092
|
-
let
|
|
2093
|
-
if ("string" == typeof
|
|
2094
|
-
const i6 = { ...s4 },
|
|
2095
|
-
|
|
2096
|
-
return await e5.call(t3,
|
|
2100
|
+
let o6 = i5[0], s4 = i5[1] || {};
|
|
2101
|
+
if ("string" == typeof o6 || o6 instanceof URL) {
|
|
2102
|
+
const i6 = { ...s4 }, r4 = new Headers(s4.headers || {});
|
|
2103
|
+
r4.delete(n), i6.headers = r4;
|
|
2104
|
+
return await e5.call(t3, o6, i6);
|
|
2097
2105
|
}
|
|
2098
|
-
if (
|
|
2099
|
-
const i6 =
|
|
2100
|
-
|
|
2101
|
-
const
|
|
2102
|
-
return await e5.call(t3,
|
|
2106
|
+
if (o6 instanceof Request) {
|
|
2107
|
+
const i6 = o6.clone(), r4 = new Headers(i6.headers);
|
|
2108
|
+
r4.delete(n);
|
|
2109
|
+
const a3 = new Request(i6, { headers: r4 });
|
|
2110
|
+
return await e5.call(t3, a3, s4);
|
|
2103
2111
|
}
|
|
2104
2112
|
return e5.apply(t3, i5);
|
|
2105
2113
|
} catch (e6) {
|
|
2106
|
-
throw
|
|
2114
|
+
throw we && console.log(`Retry without ${n} for ${o5} also failed:`, e6), e6;
|
|
2107
2115
|
}
|
|
2108
|
-
})(e4, i4,
|
|
2109
|
-
const v2 = Date.now(),
|
|
2116
|
+
})(e4, i4, o4, d3), S3 = true);
|
|
2117
|
+
const v2 = Date.now(), w2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
|
|
2110
2118
|
let I2 = null;
|
|
2111
2119
|
try {
|
|
2112
2120
|
I2 = {}, b3.headers.forEach((e5, t3) => {
|
|
2113
2121
|
I2[t3] = e5;
|
|
2114
2122
|
});
|
|
2115
2123
|
} catch (e5) {
|
|
2116
|
-
|
|
2124
|
+
we && console.warn("[Sailfish] Failed to capture response headers:", e5), I2 = null;
|
|
2117
2125
|
}
|
|
2118
|
-
const T2 = { type: 27, timestamp: v2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: v2, response_code:
|
|
2126
|
+
const T2 = { type: 27, timestamp: v2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: v2, response_code: w2, success: k2, error: x2, method: f2, url: d3, retry_without_trace_id: S3, request_headers: h2, request_body: m2, response_headers: I2, response_body: null }, ...p2 }, sendEventWithBody = (e5) => {
|
|
2119
2127
|
T2.data.response_body = e5, y2 ? y2.text().then((e6) => {
|
|
2120
2128
|
T2.data.request_body = e6, sendEvent(T2);
|
|
2121
2129
|
}, () => {
|
|
@@ -2127,7 +2135,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2127
2135
|
const t3 = e5.headers.get("content-type");
|
|
2128
2136
|
if (!t3) return false;
|
|
2129
2137
|
const n2 = t3.toLowerCase();
|
|
2130
|
-
return
|
|
2138
|
+
return l2.some((e6) => n2.includes(e6));
|
|
2131
2139
|
})(b3)) sendEventWithBody(null);
|
|
2132
2140
|
else if ((function isStreamingResponse(e5) {
|
|
2133
2141
|
const t3 = e5.headers.get("content-type");
|
|
@@ -2138,21 +2146,21 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2138
2146
|
(async function readStreamPrefix(e5, t3, n2) {
|
|
2139
2147
|
const i5 = e5.body;
|
|
2140
2148
|
if (!i5) return null;
|
|
2141
|
-
const
|
|
2142
|
-
let
|
|
2149
|
+
const o5 = i5.getReader(), s4 = new TextDecoder(), r4 = [];
|
|
2150
|
+
let a3 = 0;
|
|
2143
2151
|
const readWithLimit = async () => {
|
|
2144
2152
|
try {
|
|
2145
|
-
for (;
|
|
2146
|
-
const { done: e6, value: t4 } = await
|
|
2153
|
+
for (; a3 < t3; ) {
|
|
2154
|
+
const { done: e6, value: t4 } = await o5.read();
|
|
2147
2155
|
if (e6) break;
|
|
2148
|
-
|
|
2156
|
+
a3 += t4.byteLength, r4.push(s4.decode(t4, { stream: true }));
|
|
2149
2157
|
}
|
|
2150
|
-
return
|
|
2158
|
+
return r4.push(s4.decode()), r4.join("");
|
|
2151
2159
|
} catch {
|
|
2152
|
-
return
|
|
2160
|
+
return r4.length > 0 ? r4.join("") : null;
|
|
2153
2161
|
} finally {
|
|
2154
2162
|
try {
|
|
2155
|
-
|
|
2163
|
+
o5.cancel();
|
|
2156
2164
|
} catch {
|
|
2157
2165
|
}
|
|
2158
2166
|
}
|
|
@@ -2160,14 +2168,14 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2160
2168
|
try {
|
|
2161
2169
|
return await Promise.race([readWithLimit(), new Promise((e6) => setTimeout(() => {
|
|
2162
2170
|
try {
|
|
2163
|
-
|
|
2171
|
+
o5.cancel();
|
|
2164
2172
|
} catch {
|
|
2165
2173
|
}
|
|
2166
|
-
e6(
|
|
2174
|
+
e6(r4.length > 0 ? r4.join("") : null);
|
|
2167
2175
|
}, n2))]);
|
|
2168
2176
|
} catch {
|
|
2169
2177
|
try {
|
|
2170
|
-
|
|
2178
|
+
o5.cancel();
|
|
2171
2179
|
} catch {
|
|
2172
2180
|
}
|
|
2173
2181
|
return null;
|
|
@@ -2190,35 +2198,46 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2190
2198
|
}
|
|
2191
2199
|
return b3;
|
|
2192
2200
|
} catch (t3) {
|
|
2193
|
-
const n2 = Date.now(), s4 = false,
|
|
2194
|
-
if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(
|
|
2195
|
-
let
|
|
2201
|
+
const n2 = Date.now(), s4 = false, r4 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, a3 = t3.message || "Fetch request failed";
|
|
2202
|
+
if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Ee.toLowerCase()))) return e4.apply(i4, o4);
|
|
2203
|
+
let l3 = m2;
|
|
2196
2204
|
if (y2) try {
|
|
2197
|
-
|
|
2205
|
+
l3 = await y2.text();
|
|
2198
2206
|
} catch {
|
|
2199
|
-
|
|
2207
|
+
l3 = null;
|
|
2200
2208
|
}
|
|
2201
|
-
throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code:
|
|
2209
|
+
throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code: r4, success: s4, error: a3, method: f2, url: d3, request_headers: h2, request_body: l3, response_body: null }, ...p2 }), t3;
|
|
2202
2210
|
}
|
|
2203
|
-
})(e3, i3,
|
|
2211
|
+
})(e3, i3, o3, d2, u2, s2, c2);
|
|
2204
2212
|
} });
|
|
2205
2213
|
}
|
|
2206
|
-
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = [], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: s2, serviceIdentifier:
|
|
2214
|
+
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = [], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: s2, serviceIdentifier: r2, gitSha: a2, serviceAdditionalMetadata: l2, enableIpTracking: c2, captureStreamingResponseBody: d2 = true, captureResponseBodyMaxMb: u2 = 10, captureStreamPrefixKb: p2 = 64, captureStreamTimeoutMs: f2 = 1e4, enableFiberTracking: m2 = false, deferRecording: h2, deferRecordingStart: y2, chunkSnapshot: b2, useWsWorker: S2 = true }) {
|
|
2207
2215
|
var _a, _b;
|
|
2208
|
-
|
|
2209
|
-
|
|
2216
|
+
if ((function isHeadlessOrLighthouse() {
|
|
2217
|
+
try {
|
|
2218
|
+
if ("undefined" == typeof navigator) return false;
|
|
2219
|
+
const e3 = navigator;
|
|
2220
|
+
if (true === e3.webdriver) return true;
|
|
2221
|
+
const t3 = "string" == typeof e3.userAgent ? e3.userAgent : "";
|
|
2222
|
+
return /HeadlessChrome|Lighthouse|Chrome-Lighthouse|PTST/i.test(t3);
|
|
2223
|
+
} catch {
|
|
2224
|
+
return false;
|
|
2225
|
+
}
|
|
2226
|
+
})()) return;
|
|
2227
|
+
const v2 = h2 ?? y2 ?? true, w2 = getOrSetSessionId(), k2 = window.__sailfish_recorder || (window.__sailfish_recorder = {});
|
|
2228
|
+
if (k2.sessionId = w2, k2.apiKey = e2, k2.backendApi = t2, k2.serviceAdditionalMetadata = l2, k2.initialized && k2.sessionId === w2 && k2.ws && 1 === k2.ws.readyState) return void trackDomainChangesOnce();
|
|
2210
2229
|
const x2 = { captureStreamingResponseBody: d2, captureResponseBodyMaxMb: u2, captureStreamPrefixKb: p2, captureStreamTimeoutMs: f2 };
|
|
2211
|
-
sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }) {
|
|
2212
|
-
const
|
|
2230
|
+
sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), k2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i3 = []) {
|
|
2231
|
+
const o3 = XMLHttpRequest.prototype.open, s3 = XMLHttpRequest.prototype.send, r3 = XMLHttpRequest.prototype.setRequestHeader, a3 = getOrSetSessionId(), l3 = createSkipHeadersPropagationChecker(e3, i3);
|
|
2213
2232
|
XMLHttpRequest.prototype.setRequestHeader = function(e4, t4) {
|
|
2214
|
-
return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4,
|
|
2233
|
+
return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4, r3.call(this, e4, t4);
|
|
2215
2234
|
}, XMLHttpRequest.prototype.open = function(e4, t4, ...n2) {
|
|
2216
|
-
return this._requestUrl = "string" == typeof t4 && t4.length > 0 ? t4 : null, this._requestMethod = e4, this._capturedRequestHeaders = {},
|
|
2235
|
+
return this._requestUrl = "string" == typeof t4 && t4.length > 0 ? t4 : null, this._requestMethod = e4, this._capturedRequestHeaders = {}, o3.apply(this, [e4, t4, ...n2]);
|
|
2217
2236
|
}, XMLHttpRequest.prototype.send = function(...e4) {
|
|
2218
2237
|
const i4 = this._requestUrl;
|
|
2219
|
-
if (!i4) return
|
|
2220
|
-
if (
|
|
2221
|
-
const
|
|
2238
|
+
if (!i4) return s3.apply(this, e4);
|
|
2239
|
+
if (l3(i4)) return s3.apply(this, e4);
|
|
2240
|
+
const o4 = sessionStorage.getItem("pageVisitUUID"), r4 = uuidv4(), c3 = `${a3}/${o4}/${r4}`;
|
|
2222
2241
|
try {
|
|
2223
2242
|
this.setRequestHeader(n, c3);
|
|
2224
2243
|
} catch (e5) {
|
|
@@ -2226,29 +2245,29 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2226
2245
|
}
|
|
2227
2246
|
const d3 = getFuncSpanHeader();
|
|
2228
2247
|
if (d3) try {
|
|
2229
|
-
this.setRequestHeader(d3.name, d3.value),
|
|
2248
|
+
this.setRequestHeader(d3.name, d3.value), we && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: i4, header: d3.name });
|
|
2230
2249
|
} catch (e5) {
|
|
2231
|
-
|
|
2250
|
+
we && console.warn(`[Sailfish] Could not set funcspan header for ${i4}`, e5);
|
|
2232
2251
|
}
|
|
2233
2252
|
const u3 = Date.now();
|
|
2234
2253
|
let p3 = false;
|
|
2235
|
-
const f3 = e4[0],
|
|
2236
|
-
maskAuthorizationHeader(
|
|
2237
|
-
const emitFinished = (e5, t4, n2,
|
|
2254
|
+
const f3 = e4[0], g2 = { ...this._capturedRequestHeaders };
|
|
2255
|
+
maskAuthorizationHeader(g2);
|
|
2256
|
+
const emitFinished = (e5, t4, n2, o5, s4) => {
|
|
2238
2257
|
if (p3) return;
|
|
2239
2258
|
p3 = true;
|
|
2240
|
-
const
|
|
2241
|
-
sendEvent({ type: 27, timestamp:
|
|
2259
|
+
const l4 = Date.now();
|
|
2260
|
+
sendEvent({ type: 27, timestamp: l4, sessionId: a3, data: { request_id: r4, session_id: a3, timestamp_start: u3, timestamp_end: l4, response_code: t4, success: e5, error: n2, method: this._requestMethod, url: i4, request_headers: g2, request_body: f3, response_headers: s4, response_body: o5 }, ...getUrlAndStoredUuids() });
|
|
2242
2261
|
};
|
|
2243
2262
|
return this.addEventListener("load", () => {
|
|
2244
2263
|
const e5 = this.status || 0;
|
|
2245
2264
|
let n2, i5 = null;
|
|
2246
|
-
const
|
|
2265
|
+
const o5 = 1024 * t3.captureResponseBodyMaxMb * 1024;
|
|
2247
2266
|
try {
|
|
2248
2267
|
if (0 === t3.captureResponseBodyMaxMb) n2 = null;
|
|
2249
2268
|
else {
|
|
2250
2269
|
const e6 = this.responseText || this.response;
|
|
2251
|
-
n2 = "string" == typeof e6 && e6.length >
|
|
2270
|
+
n2 = "string" == typeof e6 && e6.length > o5 ? null : e6;
|
|
2252
2271
|
}
|
|
2253
2272
|
} catch (e6) {
|
|
2254
2273
|
n2 = null;
|
|
@@ -2261,7 +2280,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2261
2280
|
2 === t4.length && (i5[t4[0]] = t4[1]);
|
|
2262
2281
|
});
|
|
2263
2282
|
} catch (e6) {
|
|
2264
|
-
|
|
2283
|
+
we && console.warn("[Sailfish] Failed to capture XHR response headers:", e6), i5 = null;
|
|
2265
2284
|
}
|
|
2266
2285
|
if (e5 >= 200 && e5 < 300) emitFinished(true, e5, "", n2, i5);
|
|
2267
2286
|
else {
|
|
@@ -2271,26 +2290,26 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2271
2290
|
}, { once: true }), this.addEventListener("error", () => {
|
|
2272
2291
|
const e5 = this.status || 0, t4 = 0 === e5 ? "Network or CORS failure" : this.statusText || `Error ${e5}`;
|
|
2273
2292
|
emitFinished(false, e5, t4);
|
|
2274
|
-
}, { once: true }),
|
|
2293
|
+
}, { once: true }), s3.apply(this, e4);
|
|
2275
2294
|
};
|
|
2276
|
-
})(o2, x2), k2.xhrPatched = true), k2.fetchPatched || (setupFetchInterceptor(o2, x2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(
|
|
2295
|
+
})(o2, x2, i2), k2.xhrPatched = true), k2.fetchPatched || (setupFetchInterceptor(o2, x2, i2), k2.fetchPatched = true), await yieldToMain(), k2.domEventsInit || (initializeDomContentEvents(w2), k2.domEventsInit = true), await yieldToMain(), k2.consoleInit || (initializeConsolePlugin(Le, w2), k2.consoleInit = true), await yieldToMain(), k2.errorInit || (!(function initializeErrorInterceptor() {
|
|
2277
2296
|
window.addEventListener("error", (e3) => {
|
|
2278
2297
|
captureError(e3.error || e3.message);
|
|
2279
2298
|
}), window.addEventListener("unhandledrejection", (e3) => {
|
|
2280
2299
|
captureError(e3.reason, true);
|
|
2281
2300
|
});
|
|
2282
2301
|
})(), k2.errorInit = true), await yieldToMain(), _ensureModuleSideEffects(), (function storeCredentialsAndConnection({ apiKey: e3, backendApi: t3 }) {
|
|
2283
|
-
|
|
2302
|
+
g && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", t3));
|
|
2284
2303
|
})({ apiKey: e2, backendApi: t2 }), !isFunctionSpanTrackingEnabled() || k2.ws && 1 === k2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, t2).then((e3) => {
|
|
2285
2304
|
var _a2;
|
|
2286
|
-
((_a2 = e3.data) == null ? void 0 : _a2.isFunctionSpanTrackingEnabledFromApiKey) ?? false ?
|
|
2305
|
+
((_a2 = e3.data) == null ? void 0 : _a2.isFunctionSpanTrackingEnabledFromApiKey) ?? false ? we && console.log("[Sailfish] Function span tracking state validated with backend: ACTIVE") : (clearStaleFuncSpanState(), we && console.log("[Sailfish] Cleared stale function span tracking state - backend validation shows tracking is not active"));
|
|
2287
2306
|
}).catch((e3) => {
|
|
2288
|
-
|
|
2289
|
-
}), k2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...o2, ...
|
|
2307
|
+
we && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
|
|
2308
|
+
}), k2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...o2, ...Ie], t2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), k2.sentDoNotPropagateOnce = true), (async function gatherAndCacheDeviceInfo() {
|
|
2290
2309
|
sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
|
|
2291
|
-
})(), c2 && fetchAndSendIp(
|
|
2310
|
+
})(), c2 && fetchAndSendIp(w2);
|
|
2292
2311
|
try {
|
|
2293
|
-
const n2 =
|
|
2312
|
+
const n2 = a2 ?? (function readGitSha() {
|
|
2294
2313
|
var _a2;
|
|
2295
2314
|
try {
|
|
2296
2315
|
const e3 = globalThis;
|
|
@@ -2307,7 +2326,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2307
2326
|
if ("string" == typeof e3 && e3) return e3;
|
|
2308
2327
|
} catch {
|
|
2309
2328
|
}
|
|
2310
|
-
})(), i3 =
|
|
2329
|
+
})(), i3 = r2 ?? "", o3 = s2 ?? "", c3 = "JS/TS", d3 = (function getMapUuidFromWindow() {
|
|
2311
2330
|
try {
|
|
2312
2331
|
const e3 = window;
|
|
2313
2332
|
if (e3 && "string" == typeof e3.sfMapUuid && e3.sfMapUuid) return e3.sfMapUuid;
|
|
@@ -2320,89 +2339,50 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2320
2339
|
} catch {
|
|
2321
2340
|
}
|
|
2322
2341
|
const n3 = t3, i4 = [];
|
|
2323
|
-
for (const e4 of
|
|
2342
|
+
for (const e4 of oe) {
|
|
2324
2343
|
const t4 = e4(n3);
|
|
2325
2344
|
t4 && !i4.includes(t4) && i4.push(t4);
|
|
2326
2345
|
}
|
|
2327
2346
|
return { framework: i4[0] ?? null, additionalFrameworks: i4.slice(1), serviceRole: "frontend" };
|
|
2328
2347
|
})(), f3 = { ...u3, serviceRole: p3.serviceRole, ...null !== p3.framework && { framework: p3.framework }, ...p3.additionalFrameworks.length > 0 && { additionalFrameworks: p3.additionalFrameworks } };
|
|
2329
2348
|
await yieldToMain();
|
|
2330
|
-
const [
|
|
2349
|
+
const [g2, h3] = await Promise.all([fetchCaptureSettings(e2, t2), startRecordingSession(e2, w2, t2, i3, o3, d3, n2, c3, f3)]), y3 = { ...Fe, ...(_a = g2.data) == null ? void 0 : _a.captureSettingsFromApiKey, enableFiberTracking: m2 };
|
|
2331
2350
|
if (k2.ws && 1 === k2.ws.readyState) return;
|
|
2332
2351
|
if ((_b = h3.data) == null ? void 0 : _b.startRecordingSession) {
|
|
2333
2352
|
const n3 = (l2 == null ? void 0 : l2.env) || (l2 == null ? void 0 : l2.environment);
|
|
2334
2353
|
await yieldToMain();
|
|
2335
|
-
const i4 = await initializeRecording(y3, t2, e2,
|
|
2354
|
+
const i4 = await initializeRecording(y3, t2, e2, w2, n3, v2, S2, b2 ?? false);
|
|
2336
2355
|
k2.ws = i4, k2.initialized = true, trackDomainChangesOnce(), k2.sentMapUuidOnce || (!(function sendMapUuidIfAvailable(e3 = "", t3 = "") {
|
|
2337
2356
|
window.sfMapUuid && sendMessage({ type: "mapUuid", data: { mapUuid: window.sfMapUuid, serviceIdentifier: e3, serviceVersion: t3 } });
|
|
2338
|
-
})(
|
|
2357
|
+
})(r2, s2), k2.sentMapUuidOnce = true);
|
|
2339
2358
|
} else console.error("Failed to start recording session:", h3.errors || h3);
|
|
2340
2359
|
} catch (e3) {
|
|
2341
2360
|
console.error("Error starting recording:", e3);
|
|
2342
2361
|
}
|
|
2343
2362
|
}
|
|
2344
|
-
|
|
2363
|
+
exports.DEFAULT_CAPTURE_SETTINGS = Fe, exports.DEFAULT_CONSOLE_RECORDING_SETTINGS = Le, exports.STORAGE_VERSION = 1, exports.addOrUpdateMetadata = function addOrUpdateMetadata(e2) {
|
|
2364
|
+
const t2 = { type: "addOrUpdateMetadata", metadata: e2 };
|
|
2365
|
+
U && JSON.stringify(U) === JSON.stringify(e2) || (U = e2, sendMessage(t2));
|
|
2366
|
+
}, exports.buildBatches = buildBatches, exports.clearStaleFuncSpanState = clearStaleFuncSpanState, exports.createSkipHeadersPropagationChecker = createSkipHeadersPropagationChecker, exports.createTriageAndIssueFromRecorder = createTriageAndIssueFromRecorder, exports.createTriageFromRecorder = createTriageFromRecorder, exports.disableFunctionSpanTracking = disableFunctionSpanTracking, exports.enableFunctionSpanTracking = enableFunctionSpanTracking, exports.ensureHrefCache = ensureHrefCache, exports.eventSize = eventSize, exports.fetchAndSendIp = fetchAndSendIp, exports.fetchCaptureSettings = fetchCaptureSettings, exports.fetchEngineeringTicketPlatformIntegrations = fetchEngineeringTicketPlatformIntegrations, exports.fetchFunctionSpanTrackingEnabled = fetchFunctionSpanTrackingEnabled, exports.flushBufferedEvents = flushBufferedEvents, exports.getCachedHref = getCachedHref, exports.getCachedHrefNoQuery = getCachedHrefNoQuery, exports.getFuncSpanHeader = getFuncSpanHeader, exports.getOrSetSessionId = getOrSetSessionId, exports.getUrlAndStoredUuids = getUrlAndStoredUuids, exports.identify = function identify(e2, t2 = {}, n2 = false) {
|
|
2367
|
+
const i2 = { type: "identify", userId: e2, traits: t2 };
|
|
2368
|
+
O && O.userId === e2 && JSON.stringify(O.traits) === JSON.stringify(t2) || (O = { userId: e2, traits: t2, overwrite: n2 }, sendMessage(i2));
|
|
2369
|
+
}, exports.initRecorder = async (e2) => {
|
|
2345
2370
|
if ("undefined" == typeof window) return;
|
|
2346
2371
|
const t2 = window.__sailfish_recorder || (window.__sailfish_recorder = {}), n2 = getOrSetSessionId();
|
|
2347
2372
|
return clearPageVisitDataFromSessionStorage(), t2.initialized && t2.sessionId === n2 && t2.ws && 1 === t2.ws.readyState ? void 0 : (t2.initPromise || (t2.initPromise = (async () => {
|
|
2348
2373
|
if (t2.hasLoggedInitOnce || (console.log("Initializing Sailfish Recorder (first run) …"), t2.hasLoggedInitOnce = true), await startRecording(e2), !t2.issueReportingInit) {
|
|
2349
|
-
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: s2 }] = await Promise.all([Promise.resolve().then(() =>
|
|
2350
|
-
let
|
|
2374
|
+
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: s2 }] = await Promise.all([Promise.resolve().then(() => ve), Promise.resolve().then(() => le)]);
|
|
2375
|
+
let r2 = null;
|
|
2351
2376
|
try {
|
|
2352
|
-
await o2(e2.apiKey, n3),
|
|
2377
|
+
await o2(e2.apiKey, n3), r2 = s2();
|
|
2353
2378
|
} catch (e3) {
|
|
2354
2379
|
console.warn("[Sailfish] Failed to fetch integration data for issue reporting:", e3);
|
|
2355
2380
|
}
|
|
2356
|
-
i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData:
|
|
2381
|
+
i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData: r2, showEngTicketFieldsInReportIssueModalDefault: e2.showEngTicketFieldsInReportIssueModalDefault }), t2.issueReportingInit = true;
|
|
2357
2382
|
}
|
|
2358
2383
|
})().finally(() => {
|
|
2359
2384
|
delete t2.initPromise;
|
|
2360
2385
|
})), t2.initPromise);
|
|
2361
|
-
}
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
initializeWebSocket as B,
|
|
2365
|
-
invalidateUrlCache as C,
|
|
2366
|
-
Ae as D,
|
|
2367
|
-
isFunctionSpanTrackingEnabled as E,
|
|
2368
|
-
matchUrlWithWildcard as F,
|
|
2369
|
-
v as G,
|
|
2370
|
-
onNavigationChange as H,
|
|
2371
|
-
openReportIssueModal as I,
|
|
2372
|
-
restoreFuncSpanState as J,
|
|
2373
|
-
sendDomainsToNotPropagateHeaderTo as K,
|
|
2374
|
-
sendEvent as L,
|
|
2375
|
-
sendGraphQLRequest as M,
|
|
2376
|
-
sendMessage as N,
|
|
2377
|
-
startRecording as O,
|
|
2378
|
-
startRecordingSession as P,
|
|
2379
|
-
trackingEvent as Q,
|
|
2380
|
-
withAppUrlMetadata as R,
|
|
2381
|
-
Fe as S,
|
|
2382
|
-
Re as a,
|
|
2383
|
-
addOrUpdateMetadata as b,
|
|
2384
|
-
buildBatches as c,
|
|
2385
|
-
clearStaleFuncSpanState as d,
|
|
2386
|
-
createTriageAndIssueFromRecorder as e,
|
|
2387
|
-
createTriageFromRecorder as f,
|
|
2388
|
-
disableFunctionSpanTracking as g,
|
|
2389
|
-
enableFunctionSpanTracking as h,
|
|
2390
|
-
ensureHrefCache as i,
|
|
2391
|
-
eventSize as j,
|
|
2392
|
-
fetchAndSendIp as k,
|
|
2393
|
-
fetchCaptureSettings as l,
|
|
2394
|
-
fetchEngineeringTicketPlatformIntegrations as m,
|
|
2395
|
-
fetchFunctionSpanTrackingEnabled as n,
|
|
2396
|
-
flushBufferedEvents as o,
|
|
2397
|
-
getCachedHref as p,
|
|
2398
|
-
getCachedHrefNoQuery as q,
|
|
2399
|
-
getFuncSpanHeader as r,
|
|
2400
|
-
getOrSetSessionId as s,
|
|
2401
|
-
getUrlAndStoredUuids as t,
|
|
2402
|
-
identify as u,
|
|
2403
|
-
initRecorder as v,
|
|
2404
|
-
initializeConsolePlugin as w,
|
|
2405
|
-
initializeDomContentEvents as x,
|
|
2406
|
-
yieldToMain as y,
|
|
2407
|
-
initializeFunctionSpanTrackingFromApi as z
|
|
2408
|
-
};
|
|
2386
|
+
}, exports.initializeConsolePlugin = initializeConsolePlugin, exports.initializeDomContentEvents = initializeDomContentEvents, exports.initializeFunctionSpanTrackingFromApi = initializeFunctionSpanTrackingFromApi, exports.initializeRecording = initializeRecording, exports.initializeWebSocket = initializeWebSocket, exports.invalidateUrlCache = invalidateUrlCache, exports.isFunctionSpanTrackingEnabled = isFunctionSpanTrackingEnabled, exports.matchUrlWithWildcard = matchUrlWithWildcard, exports.onNavigationChange = onNavigationChange, exports.openReportIssueModal = openReportIssueModal, exports.restoreFuncSpanState = restoreFuncSpanState, exports.sendDomainsToNotPropagateHeaderTo = sendDomainsToNotPropagateHeaderTo, exports.sendEvent = sendEvent, exports.sendGraphQLRequest = sendGraphQLRequest, exports.sendMessage = sendMessage, exports.startRecording = startRecording, exports.startRecordingSession = startRecordingSession, exports.trackingEvent = function trackingEvent(e2) {
|
|
2387
|
+
sendMessage({ type: "trackingEvent", trackingData: e2, timestamp: exports.nowTimestamp() });
|
|
2388
|
+
}, exports.withAppUrlMetadata = withAppUrlMetadata, exports.yieldToMain = yieldToMain;
|