@sailfish-ai/recorder 1.11.3 → 1.11.4
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-jzbHv2wf.js → chunkSerializer-CFHDS9Vi.js} +1 -1
- package/dist/chunks/chunkSerializer-CFHDS9Vi.js.br +0 -0
- package/dist/chunks/chunkSerializer-CFHDS9Vi.js.gz +0 -0
- package/dist/chunks/{chunkSerializer-CV4nkb5-.js → chunkSerializer-DOaGGlCg.js} +1 -1
- package/dist/chunks/chunkSerializer-DOaGGlCg.js.br +0 -0
- package/dist/chunks/chunkSerializer-DOaGGlCg.js.gz +0 -0
- package/dist/chunks/{index-BynFTRFv.js → index-B8IAZfT7.js} +220 -192
- package/dist/chunks/index-B8IAZfT7.js.br +0 -0
- package/dist/chunks/index-B8IAZfT7.js.gz +0 -0
- package/dist/chunks/{index-BP-kNUGS.js → index-DbcegHRc.js} +313 -285
- package/dist/chunks/index-DbcegHRc.js.br +0 -0
- package/dist/chunks/index-DbcegHRc.js.gz +0 -0
- package/dist/inAppReportIssueModal/index.js +10 -4
- package/dist/inAppReportIssueModal/index.js.br +0 -0
- package/dist/inAppReportIssueModal/index.js.gz +0 -0
- package/dist/inAppReportIssueModal/integrations.js +50 -0
- package/dist/inAppReportIssueModal/integrations.js.br +0 -0
- package/dist/inAppReportIssueModal/integrations.js.gz +0 -0
- package/dist/recorder.cjs +1 -1
- package/dist/recorder.cjs.br +0 -0
- package/dist/recorder.cjs.gz +0 -0
- package/dist/recorder.js +1 -1
- package/dist/recorder.js.br +0 -0
- package/dist/recorder.js.gz +0 -0
- package/dist/recorder.umd.cjs +34 -6
- package/dist/recorder.umd.cjs.br +0 -0
- package/dist/recorder.umd.cjs.gz +0 -0
- package/dist/types/inAppReportIssueModal/integrations.d.ts +3 -0
- package/package.json +1 -1
- package/dist/chunks/chunkSerializer-CV4nkb5-.js.br +0 -0
- package/dist/chunks/chunkSerializer-CV4nkb5-.js.gz +0 -0
- package/dist/chunks/chunkSerializer-jzbHv2wf.js.br +0 -0
- package/dist/chunks/chunkSerializer-jzbHv2wf.js.gz +0 -0
- package/dist/chunks/index-BP-kNUGS.js.br +0 -0
- package/dist/chunks/index-BP-kNUGS.js.gz +0 -0
- package/dist/chunks/index-BynFTRFv.js.br +0 -0
- package/dist/chunks/index-BynFTRFv.js.gz +0 -0
|
@@ -57,7 +57,7 @@ function uuidv4() {
|
|
|
57
57
|
return ("x" === e2 ? t2 : 3 & t2 | 8).toString(16);
|
|
58
58
|
});
|
|
59
59
|
}
|
|
60
|
-
const n = "X-Sf3-Rid", i = 0, o = 1,
|
|
60
|
+
const n = "X-Sf3-Rid", i = 0, o = 1, r = 2, s = 4, a = "recordingEvents";
|
|
61
61
|
let l = null;
|
|
62
62
|
function openDb$1() {
|
|
63
63
|
return (function hasIndexedDB$1() {
|
|
@@ -79,8 +79,8 @@ function openDb$1() {
|
|
|
79
79
|
function withStore$1(e2, t2) {
|
|
80
80
|
return openDb$1().then((n2) => n2 ? new Promise((i2) => {
|
|
81
81
|
try {
|
|
82
|
-
const o2 = n2.transaction(a, e2),
|
|
83
|
-
Promise.resolve(t2(
|
|
82
|
+
const o2 = n2.transaction(a, e2), r2 = o2.objectStore(a);
|
|
83
|
+
Promise.resolve(t2(r2)).then((e3) => {
|
|
84
84
|
o2.oncomplete = () => i2(e3), o2.onerror = () => i2(null);
|
|
85
85
|
}).catch(() => i2(null));
|
|
86
86
|
} catch {
|
|
@@ -114,8 +114,8 @@ async function withStore(e2, t2) {
|
|
|
114
114
|
const n2 = await openDb();
|
|
115
115
|
return n2 ? new Promise((i2) => {
|
|
116
116
|
try {
|
|
117
|
-
const o2 = n2.transaction(c, e2),
|
|
118
|
-
Promise.resolve(t2(
|
|
117
|
+
const o2 = n2.transaction(c, e2), r2 = o2.objectStore(c);
|
|
118
|
+
Promise.resolve(t2(r2)).then((e3) => {
|
|
119
119
|
o2.oncomplete = () => i2(e3), o2.onerror = () => i2(null);
|
|
120
120
|
}).catch(() => i2(null));
|
|
121
121
|
} catch {
|
|
@@ -160,13 +160,13 @@ function buildBatches(e2, t2, n2) {
|
|
|
160
160
|
}
|
|
161
161
|
const o2 = [];
|
|
162
162
|
for (const e3 in i2) {
|
|
163
|
-
const
|
|
164
|
-
let
|
|
165
|
-
for (const e4 of
|
|
163
|
+
const r2 = i2[e3];
|
|
164
|
+
let s2 = [], a2 = 0;
|
|
165
|
+
for (const e4 of r2) {
|
|
166
166
|
const i3 = t2(e4);
|
|
167
|
-
a2 + i3 > n2 && (
|
|
167
|
+
a2 + i3 > n2 && (s2.length > 0 && (o2.push(s2), s2 = [], a2 = 0), i3 > n2) || (s2.push(e4), a2 += i3);
|
|
168
168
|
}
|
|
169
|
-
|
|
169
|
+
s2.length > 0 && o2.push(s2);
|
|
170
170
|
}
|
|
171
171
|
return o2;
|
|
172
172
|
}
|
|
@@ -178,8 +178,8 @@ function withAppUrlMetadata(e2) {
|
|
|
178
178
|
return { ...e2 ?? {}, appUrl: (e2 == null ? void 0 : e2.appUrl) ?? ((_a = window == null ? void 0 : window.location) == null ? void 0 : _a.href) };
|
|
179
179
|
}
|
|
180
180
|
exports.nowTimestamp = Date.now, /[1-9][0-9]{12}/.test(Date.now().toString()) || (exports.nowTimestamp = () => (/* @__PURE__ */ new Date()).getTime());
|
|
181
|
-
const
|
|
182
|
-
let
|
|
181
|
+
const S = readDebugFlag(), v = "per_session";
|
|
182
|
+
let w = null, k = null, x = false, I = null, T = null, E = "", C = "", $ = false;
|
|
183
183
|
const F = [];
|
|
184
184
|
function onNavigationChange(e2) {
|
|
185
185
|
F.push(e2);
|
|
@@ -210,24 +210,24 @@ function getCachedHrefNoQuery() {
|
|
|
210
210
|
return C || ("undefined" != typeof window ? window.location.origin + window.location.pathname : "");
|
|
211
211
|
}
|
|
212
212
|
const L = [];
|
|
213
|
-
let
|
|
213
|
+
let A = null;
|
|
214
214
|
function queueEventForIDB(e2) {
|
|
215
|
-
L.push(e2), L.length >= 50 ? _flushIDBQueue() :
|
|
215
|
+
L.push(e2), L.length >= 50 ? _flushIDBQueue() : A || (A = setTimeout(_flushIDBQueue, 100));
|
|
216
216
|
}
|
|
217
217
|
function _flushIDBQueue() {
|
|
218
|
-
if (
|
|
218
|
+
if (A && (clearTimeout(A), A = null), 0 === L.length) return;
|
|
219
219
|
!(async function saveEventsToIDB(e2) {
|
|
220
220
|
await withStore$1("readwrite", async (t2) => {
|
|
221
221
|
for (const n2 of e2) t2.add({ timestamp: Date.now(), data: n2 });
|
|
222
222
|
});
|
|
223
223
|
})(L.splice(0));
|
|
224
224
|
}
|
|
225
|
-
let
|
|
225
|
+
let M = false, R = null, D = null, P = false;
|
|
226
226
|
const _ = "sailfish_funcspan_global_state";
|
|
227
227
|
function wsSendPayload(e2) {
|
|
228
228
|
if (!isWebSocketOpen(k)) return false;
|
|
229
|
-
if (
|
|
230
|
-
return
|
|
229
|
+
if (w) try {
|
|
230
|
+
return w.postMessage({ type: "send", payload: e2 }), true;
|
|
231
231
|
} catch {
|
|
232
232
|
return false;
|
|
233
233
|
}
|
|
@@ -239,8 +239,8 @@ function wsSendPayload(e2) {
|
|
|
239
239
|
}
|
|
240
240
|
function wsSendRaw(e2) {
|
|
241
241
|
if (!isWebSocketOpen(k)) return false;
|
|
242
|
-
if (
|
|
243
|
-
return
|
|
242
|
+
if (w) try {
|
|
243
|
+
return w.postMessage({ type: "sendRaw", payload: e2 }), true;
|
|
244
244
|
} catch {
|
|
245
245
|
return false;
|
|
246
246
|
}
|
|
@@ -254,21 +254,21 @@ function saveGlobalFuncSpanState(e2, t2) {
|
|
|
254
254
|
try {
|
|
255
255
|
if ("undefined" == typeof localStorage) return;
|
|
256
256
|
const n2 = { enabled: e2, expirationTimestampMs: t2, savedAt: Date.now() };
|
|
257
|
-
localStorage.setItem(_, JSON.stringify(n2)),
|
|
257
|
+
localStorage.setItem(_, JSON.stringify(n2)), S && console.log("[Sailfish] Saved funcSpan state to localStorage:", n2);
|
|
258
258
|
} catch (e3) {
|
|
259
|
-
|
|
259
|
+
S && console.warn("[Sailfish] Failed to save funcSpan state to localStorage:", e3);
|
|
260
260
|
}
|
|
261
261
|
}
|
|
262
262
|
function clearGlobalFuncSpanState() {
|
|
263
263
|
try {
|
|
264
264
|
if ("undefined" == typeof localStorage) return;
|
|
265
|
-
localStorage.removeItem(_),
|
|
265
|
+
localStorage.removeItem(_), S && console.log("[Sailfish] Cleared funcSpan state from localStorage");
|
|
266
266
|
} catch (e2) {
|
|
267
|
-
|
|
267
|
+
S && console.warn("[Sailfish] Failed to clear funcSpan state from localStorage:", e2);
|
|
268
268
|
}
|
|
269
269
|
}
|
|
270
270
|
function clearStaleFuncSpanState() {
|
|
271
|
-
|
|
271
|
+
M = false, D = null, P = false, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Cleared stale function span tracking state (backend validation failed)");
|
|
272
272
|
}
|
|
273
273
|
let B = false;
|
|
274
274
|
function restoreFuncSpanState() {
|
|
@@ -280,14 +280,14 @@ function restoreFuncSpanState() {
|
|
|
280
280
|
const e3 = localStorage.getItem(_);
|
|
281
281
|
if (!e3) return null;
|
|
282
282
|
const t2 = JSON.parse(e3);
|
|
283
|
-
return
|
|
283
|
+
return S && console.log("[Sailfish] Loaded funcSpan state from localStorage:", t2), t2;
|
|
284
284
|
} catch (e3) {
|
|
285
|
-
return
|
|
285
|
+
return S && console.warn("[Sailfish] Failed to load funcSpan state from localStorage:", e3), null;
|
|
286
286
|
}
|
|
287
287
|
})();
|
|
288
|
-
if (e2 && e2.enabled) if (
|
|
289
|
-
Date.now() >= D ? (
|
|
290
|
-
} else
|
|
288
|
+
if (e2 && e2.enabled) if (M = true, D = e2.expirationTimestampMs, P = false, S && console.log("[Sailfish] Restored global function span tracking from localStorage:", { enabled: true, expirationTime: D }), null !== D) {
|
|
289
|
+
Date.now() >= D ? (M = 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)");
|
|
290
|
+
} else S && console.log("[Sailfish] Function span tracking is active (no expiration, temporary until WebSocket confirms)");
|
|
291
291
|
}
|
|
292
292
|
function isWebSocketOpen(e2) {
|
|
293
293
|
return (e2 == null ? void 0 : e2.readyState) === WebSocket.OPEN;
|
|
@@ -345,7 +345,7 @@ function sendEvent(e2) {
|
|
|
345
345
|
e2.app_url || (e2.app_url = getCachedHref()), !x && isWebSocketOpen(k) && wsSendPayload({ type: "event", event: e2, mapUuid: window.sfMapUuid }) || queueEventForIDB(e2);
|
|
346
346
|
}
|
|
347
347
|
function handleWsOpen() {
|
|
348
|
-
|
|
348
|
+
S && (console.log("[Sailfish] WebSocket connection opened"), console.log("[Sailfish] Function span tracking state: " + (M ? "ENABLED" : "DISABLED"))), (async () => {
|
|
349
349
|
try {
|
|
350
350
|
x = true, await flushNotifyQueue(), await flushBufferedEvents();
|
|
351
351
|
} finally {
|
|
@@ -357,42 +357,42 @@ function handleWsOpen() {
|
|
|
357
357
|
})();
|
|
358
358
|
}
|
|
359
359
|
function handleWsClose() {
|
|
360
|
-
null != T && (clearInterval(T), T = null),
|
|
360
|
+
null != T && (clearInterval(T), T = null), S && console.log("[Sailfish] WebSocket closed");
|
|
361
361
|
}
|
|
362
362
|
function handleWsMessage(e2) {
|
|
363
363
|
try {
|
|
364
364
|
const t2 = JSON.parse(e2);
|
|
365
|
-
if ("funcSpanTrackingControl" === t2.type) if (
|
|
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), M = t2.enabled, P = false, S && console.log("[Sailfish] Function span tracking " + (t2.enabled ? "ENABLED (GLOBAL)" : "DISABLED (GLOBAL)")), t2.enabled) {
|
|
366
366
|
if (t2.expirationTimestampMs) {
|
|
367
367
|
D = t2.expirationTimestampMs;
|
|
368
368
|
const e3 = Date.now(), n2 = D - e3;
|
|
369
|
-
|
|
370
|
-
P || (
|
|
371
|
-
}, n2)) : (
|
|
369
|
+
S && console.log(`[Sailfish] Server expiration timestamp: ${D}, ms until expiration: ${n2}`), n2 > 0 ? (saveGlobalFuncSpanState(true, D), R = window.setTimeout(() => {
|
|
370
|
+
P || (M = 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)) : (M = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Tracking already expired, not enabling"));
|
|
372
372
|
} else {
|
|
373
373
|
const e3 = t2.timeoutSeconds || 3600;
|
|
374
374
|
e3 > 0 && (D = Date.now() + 1e3 * e3, saveGlobalFuncSpanState(true, D), R = window.setTimeout(() => {
|
|
375
|
-
P || (
|
|
375
|
+
P || (M = 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)"));
|
|
376
376
|
}, 1e3 * e3));
|
|
377
377
|
}
|
|
378
378
|
try {
|
|
379
379
|
const e3 = getOrSetSessionId();
|
|
380
|
-
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }),
|
|
380
|
+
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: e3, enabled: true, configurationType: "global" }), S && console.log(`[Sailfish] GLOBAL tracking session report sent for session: ${e3}`);
|
|
381
381
|
} catch (e3) {
|
|
382
|
-
|
|
382
|
+
S && console.warn("[Sailfish] Failed to send GLOBAL tracking session report:", e3);
|
|
383
383
|
}
|
|
384
384
|
} else D = null, clearGlobalFuncSpanState();
|
|
385
385
|
} catch (e3) {
|
|
386
386
|
}
|
|
387
387
|
}
|
|
388
|
-
function initializeWebSocket(t2, n2, i2, o2,
|
|
388
|
+
function initializeWebSocket(t2, n2, i2, o2, r2 = false) {
|
|
389
389
|
ensureHrefCache();
|
|
390
|
-
const
|
|
390
|
+
const s2 = (function getWebSocketHost(e2) {
|
|
391
391
|
const t3 = new URL(e2);
|
|
392
392
|
return `${t3.hostname}${t3.port ? `:${t3.port}` : ""}`;
|
|
393
393
|
})(t2);
|
|
394
|
-
let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${
|
|
395
|
-
if (o2 && (a2 += `&envValue=${encodeURIComponent(o2)}`),
|
|
394
|
+
let a2 = `${"https:" === new URL(t2).protocol ? "wss" : "ws"}://${s2}/ws/notify/?apiKey=${n2}&sessionId=${i2}&sender=JS%2FTS&version=1.11.4`;
|
|
395
|
+
if (o2 && (a2 += `&envValue=${encodeURIComponent(o2)}`), w = r2 ? (function tryCreateWsWorker() {
|
|
396
396
|
if ("undefined" == typeof Worker) return null;
|
|
397
397
|
try {
|
|
398
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);
|
|
@@ -400,18 +400,18 @@ function initializeWebSocket(t2, n2, i2, o2, s2 = false) {
|
|
|
400
400
|
} catch {
|
|
401
401
|
return null;
|
|
402
402
|
}
|
|
403
|
-
})() : null,
|
|
404
|
-
const e2 =
|
|
405
|
-
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);
|
|
406
406
|
} };
|
|
407
|
-
return k = t3,
|
|
407
|
+
return k = t3, w.onmessage = (e3) => {
|
|
408
408
|
const n3 = e3.data;
|
|
409
409
|
"open" === n3.type ? (t3.readyState = WebSocket.OPEN, handleWsOpen()) : "close" === n3.type ? (t3.readyState = WebSocket.CLOSED, handleWsClose()) : "message" === n3.type && handleWsMessage(n3.data);
|
|
410
|
-
},
|
|
411
|
-
|
|
412
|
-
},
|
|
410
|
+
}, w.onerror = () => {
|
|
411
|
+
S && console.warn("[Sailfish] WebSocket worker error");
|
|
412
|
+
}, w.postMessage({ type: "init", wsUrl: a2 }), S && console.log("[Sailfish] WebSocket running in Web Worker (off main thread)"), t3;
|
|
413
413
|
}
|
|
414
|
-
|
|
414
|
+
S && console.log("[Sailfish] WebSocket running on main thread (Worker unavailable)");
|
|
415
415
|
const l2 = new e(a2, [], { connectionTimeout: 3e4 }), c2 = { get readyState() {
|
|
416
416
|
return l2.readyState;
|
|
417
417
|
}, close: () => {
|
|
@@ -423,26 +423,26 @@ function sendMessage(e2) {
|
|
|
423
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));
|
|
424
424
|
}
|
|
425
425
|
function enableFunctionSpanTracking() {
|
|
426
|
-
if (
|
|
427
|
-
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType:
|
|
428
|
-
} else
|
|
426
|
+
if (S && console.log("[Sailfish] enableFunctionSpanTracking() called - Report Issue recording started (LOCAL MODE)"), M = true, P = true, D = null, null !== R && (window.clearTimeout(R), R = null), isWebSocketOpen(k)) {
|
|
427
|
+
wsSendPayload({ type: "funcSpanTrackingSessionReport", sessionId: getOrSetSessionId(), enabled: true, configurationType: v });
|
|
428
|
+
} else S && console.warn("[Sailfish] WebSocket not open, cannot report LOCAL tracking session");
|
|
429
429
|
}
|
|
430
430
|
function disableFunctionSpanTracking() {
|
|
431
|
-
if (
|
|
432
|
-
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 });
|
|
433
433
|
} else console.warn("[FUNCSPAN STOP] ✗ WebSocket not open, cannot notify tracking end");
|
|
434
|
-
P && (
|
|
434
|
+
P && (M = false, P = false, D = null, S && console.log("[Sailfish] LOCAL tracking mode disabled")), null !== R && (window.clearTimeout(R), R = null);
|
|
435
435
|
}
|
|
436
436
|
function isFunctionSpanTrackingEnabled() {
|
|
437
|
-
return
|
|
437
|
+
return M;
|
|
438
438
|
}
|
|
439
439
|
function initializeFunctionSpanTrackingFromApi(e2) {
|
|
440
|
-
e2 && !
|
|
440
|
+
e2 && !M ? (M = true, P = false, D = null, S && console.log("[Sailfish] Function span tracking initialized as ENABLED from API check")) : !e2 && M && (M = false, P = false, D = null, S && console.log("[Sailfish] Function span tracking initialized as DISABLED from API check"));
|
|
441
441
|
}
|
|
442
442
|
function getFuncSpanHeader() {
|
|
443
|
-
if (!
|
|
443
|
+
if (!M) return null;
|
|
444
444
|
if (null !== D) {
|
|
445
|
-
if (Date.now() >= D) return
|
|
445
|
+
if (Date.now() >= D) return M = false, D = null, clearGlobalFuncSpanState(), S && console.log("[Sailfish] Function span tracking expired on header check - disabling now"), null;
|
|
446
446
|
}
|
|
447
447
|
return { name: "X-Sf3-FunctionSpanCaptureOverride", value: "1-1-10-10-1-1.0-1-0-0" };
|
|
448
448
|
}
|
|
@@ -458,8 +458,8 @@ function fetchAndSendIp(e2) {
|
|
|
458
458
|
for (const e3 of N) try {
|
|
459
459
|
const t2 = new AbortController(), n2 = setTimeout(() => t2.abort(), 5e3), i2 = await fetch(e3, { signal: t2.signal });
|
|
460
460
|
if (clearTimeout(n2), !i2.ok) continue;
|
|
461
|
-
const o2 = await i2.json(),
|
|
462
|
-
if (
|
|
461
|
+
const o2 = await i2.json(), r2 = o2.ip || o2.origin || null;
|
|
462
|
+
if (r2 && "string" == typeof r2 && r2.length <= 45) return void sendMessage({ type: "visitorIp", ip: r2, timestamp: exports.nowTimestamp() });
|
|
463
463
|
} catch {
|
|
464
464
|
}
|
|
465
465
|
z = null;
|
|
@@ -498,7 +498,7 @@ async function captureError(e2, t2 = false) {
|
|
|
498
498
|
n3.push(e4);
|
|
499
499
|
continue;
|
|
500
500
|
}
|
|
501
|
-
const [, i3, o3,
|
|
501
|
+
const [, i3, o3, r3, s3] = t4, a3 = parseInt(r3, 10), l2 = Math.max(0, parseInt(s3, 10) - 1);
|
|
502
502
|
if (!Number.isFinite(a3) || !Number.isFinite(l2)) {
|
|
503
503
|
n3.push(e4 + " [Invalid line/column]");
|
|
504
504
|
continue;
|
|
@@ -517,29 +517,29 @@ async function captureError(e2, t2 = false) {
|
|
|
517
517
|
} else n3.push(`${e4} [No mapping found in ${o3}]`);
|
|
518
518
|
}
|
|
519
519
|
return n3;
|
|
520
|
-
})(i2),
|
|
521
|
-
sendMessage({ type: "event", event: { type: 6, timestamp: a2, data: { payload: { message: n2, stack: i2, trace:
|
|
520
|
+
})(i2), r2 = o2.filter((e3) => !e3.includes("chunk-") && !e3.includes("react-dom")), s2 = r2.length > 0 ? r2 : o2, a2 = Date.now();
|
|
521
|
+
sendMessage({ type: "event", event: { type: 6, timestamp: a2, data: { payload: { message: n2, stack: i2, trace: s2, filteredStack: r2, userAgent: navigator.userAgent, url: window.location.href, timestamp: a2, level: "error" } } } });
|
|
522
522
|
}
|
|
523
523
|
const K = readDebugFlag();
|
|
524
524
|
const G = readDebugFlag();
|
|
525
|
-
function sendGraphQLRequest(e2, t2, n2, i2 = 5, o2 = 2e3,
|
|
526
|
-
const
|
|
527
|
-
return G && console.log(`Initial GraphQL request for ${e2} at ${
|
|
528
|
-
let
|
|
525
|
+
function sendGraphQLRequest(e2, t2, n2, i2 = 5, o2 = 2e3, r2 = 2) {
|
|
526
|
+
const s2 = `${n2.backendApi}/graphql/?apiKey=${n2.apiKey}`;
|
|
527
|
+
return G && console.log(`Initial GraphQL request for ${e2} at ${s2}`), (function exponentialBackoff(e3, t3, n3 = 5, i3 = 2e3, o3 = 2) {
|
|
528
|
+
let r3 = 0;
|
|
529
529
|
const attemptRequest = async () => {
|
|
530
530
|
try {
|
|
531
531
|
return await e3();
|
|
532
532
|
} catch (e4) {
|
|
533
|
-
if (
|
|
534
|
-
const
|
|
535
|
-
return K && console.log(`Attempt ${
|
|
533
|
+
if (r3++, r3 > n3) throw e4;
|
|
534
|
+
const s3 = i3 * Math.pow(o3, r3 - 1);
|
|
535
|
+
return K && console.log(`Attempt ${r3} failed: ${t3}; Retrying in ${s3}ms...`), await new Promise((e5) => setTimeout(e5, s3)), attemptRequest();
|
|
536
536
|
}
|
|
537
537
|
};
|
|
538
538
|
return attemptRequest();
|
|
539
|
-
})(() => fetch(
|
|
539
|
+
})(() => fetch(s2, { method: "POST", headers: { "Content-Type": "application/json" }, body: JSON.stringify({ operationName: e2, query: t2, variables: n2 }) }).then((e3) => {
|
|
540
540
|
if (G && console.log(`Received response with status: ${e3.status}`), !e3.ok) throw new Error(`GraphQL request failed with status ${e3.status}`);
|
|
541
541
|
return e3.json();
|
|
542
|
-
}), "Sending GraphQL request to Sailfish AI", i2, o2,
|
|
542
|
+
}), "Sending GraphQL request to Sailfish AI", i2, o2, r2);
|
|
543
543
|
}
|
|
544
544
|
function fetchCaptureSettings(e2, t2) {
|
|
545
545
|
return sendGraphQLRequest("GetCaptureSettingsFromApiKey", "\n query GetCaptureSettingsFromApiKey($apiKey: String!) {\n captureSettingsFromApiKey(apiKey: $apiKey) {\n recordCanvas\n recordCrossOriginIframes\n collectFonts\n inlineImages\n recordPassword\n recordRealName\n recordCreditCardInfo\n recordSsn\n recordDob\n sampling\n textEditThrottleEnabled\n }\n }\n ", { apiKey: e2, backendApi: t2 });
|
|
@@ -547,20 +547,20 @@ function fetchCaptureSettings(e2, t2) {
|
|
|
547
547
|
function fetchFunctionSpanTrackingEnabled(e2, t2) {
|
|
548
548
|
return sendGraphQLRequest("GetFunctionSpanTrackingEnabledFromApiKey", "\n query GetFunctionSpanTrackingEnabledFromApiKey($apiKey: String!) {\n isFunctionSpanTrackingEnabledFromApiKey(apiKey: $apiKey)\n }\n ", { apiKey: e2, backendApi: t2 });
|
|
549
549
|
}
|
|
550
|
-
function startRecordingSession(e2, t2, n2, i2, o2,
|
|
551
|
-
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:
|
|
550
|
+
function startRecordingSession(e2, t2, n2, i2, o2, r2, s2, a2, l2) {
|
|
551
|
+
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: r2, gitSha: s2, library: a2, serviceAdditionalMetadata: l2, startRecordingFilePath: null, startRecordingLineNumber: null });
|
|
552
552
|
}
|
|
553
553
|
function sendDomainsToNotPropagateHeaderTo(e2, t2, n2) {
|
|
554
554
|
return sendGraphQLRequest("DomainsToNotPassHeaderTo", "mutation DomainsToNotPassHeaderTo($apiKey: String!, $domains: [String!]!) {\n domainsToNotPassHeaderTo(apiKey: $apiKey, domains: $domains)\n }", { apiKey: e2, domains: t2, backendApi: n2 });
|
|
555
555
|
}
|
|
556
|
-
function createTriageFromRecorder(e2, t2, n2, i2, o2,
|
|
557
|
-
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:
|
|
556
|
+
function createTriageFromRecorder(e2, t2, n2, i2, o2, r2, s2) {
|
|
557
|
+
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: r2, triageSource: s2, backendApi: t2 });
|
|
558
558
|
}
|
|
559
559
|
function fetchEngineeringTicketPlatformIntegrations(e2, t2) {
|
|
560
560
|
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 });
|
|
561
561
|
}
|
|
562
|
-
function createTriageAndIssueFromRecorder(e2, t2, n2, i2, o2,
|
|
563
|
-
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:
|
|
562
|
+
function createTriageAndIssueFromRecorder(e2, t2, n2, i2, o2, r2, s2, a2, l2, c2, d2, u2, p2, f2, g2, m2) {
|
|
563
|
+
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: r2, issueName: s2, issueDescription: a2, createEngineeringTicket: l2, teamId: c2, projectId: d2, priority: u2, labels: p2, issueType: f2, customFields: g2, triageSource: m2, backendApi: t2 });
|
|
564
564
|
}
|
|
565
565
|
const V = ["/node_modules/", "/@sailfish-ai/", "/@sailfish-rrweb/", "/dist/", "/webpack/", "/vite/", "/__vite", "/react-dom/", "/react/", "/scheduler/", "/<", "/chrome-extension://", "/extensions/"];
|
|
566
566
|
function shouldSkipFrame(e2) {
|
|
@@ -662,13 +662,13 @@ function initializeDomContentEvents(e2) {
|
|
|
662
662
|
t2.data.source = i;
|
|
663
663
|
break;
|
|
664
664
|
case "complete":
|
|
665
|
-
t2.data.source =
|
|
665
|
+
t2.data.source = r;
|
|
666
666
|
}
|
|
667
667
|
t2.data.info && sendEvent(t2);
|
|
668
668
|
}), document.addEventListener("DOMContentLoaded", () => {
|
|
669
669
|
sendEvent({ type: 24, data: { source: o }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() });
|
|
670
670
|
}), window.addEventListener("pagehide", () => {
|
|
671
|
-
sendEvent({ type: 24, data: { source:
|
|
671
|
+
sendEvent({ type: 24, data: { source: s }, timestamp: Date.now(), sessionId: e2, ...getUrlAndStoredUuids() });
|
|
672
672
|
});
|
|
673
673
|
}
|
|
674
674
|
async function initializePerformancePlugin(e2) {
|
|
@@ -688,14 +688,14 @@ async function initializePerformancePlugin(e2) {
|
|
|
688
688
|
async function initializeConsolePlugin(e2, n2) {
|
|
689
689
|
const { getRecordConsolePlugin: i2 } = await import("@sailfish-rrweb/rrweb-plugin-console-record");
|
|
690
690
|
await yieldToMain();
|
|
691
|
-
const { name: o2, observer:
|
|
692
|
-
|
|
693
|
-
const i3 = e3, [
|
|
691
|
+
const { name: o2, observer: r2 } = i2(e2);
|
|
692
|
+
r2((e3) => {
|
|
693
|
+
const i3 = e3, [r3, s2] = getCallerLocationFromTrace(i3 == null ? void 0 : i3.trace, 0), [a2, l2] = getCallerLocation(2), c2 = r3 ?? a2, d2 = s2 ?? l2, u2 = { ...i3, sourceFile: c2, sourceLine: d2 };
|
|
694
694
|
sendEvent({ type: t.EventType.Plugin, timestamp: Date.now(), data: { plugin: o2, payload: u2 }, sessionId: n2, ...getUrlAndStoredUuids() });
|
|
695
695
|
}, window, e2);
|
|
696
696
|
}
|
|
697
|
-
async function initializeRecording(e2, n2, i2, o2,
|
|
698
|
-
const c2 = initializeWebSocket(n2, i2, o2,
|
|
697
|
+
async function initializeRecording(e2, n2, i2, o2, r2, s2 = true, a2 = false, l2 = false) {
|
|
698
|
+
const c2 = initializeWebSocket(n2, i2, o2, r2, a2);
|
|
699
699
|
try {
|
|
700
700
|
const n3 = (function createThrottledEmit(e3, t2 = 1e3) {
|
|
701
701
|
if (!e3) return { emit: (e4) => sendEvent(e4), flush: () => {
|
|
@@ -710,8 +710,8 @@ async function initializeRecording(e2, n2, i2, o2, s2, r2 = true, a2 = false, l2
|
|
|
710
710
|
const t3 = e4.data, n5 = (t3 == null ? void 0 : t3.adds) && t3.adds.length > 0, i4 = (t3 == null ? void 0 : t3.removes) && t3.removes.length > 0;
|
|
711
711
|
if (n5 || i4) return void sendEvent(e4);
|
|
712
712
|
}
|
|
713
|
-
const
|
|
714
|
-
n4.set(
|
|
713
|
+
const r3 = `3:${o3}:${((_b = e4.data) == null ? void 0 : _b.id) || "unknown"}`;
|
|
714
|
+
n4.set(r3, e4), i3 || (i3 = setInterval(() => {
|
|
715
715
|
0 !== n4.size && (n4.forEach((e5) => sendEvent(e5)), n4.clear());
|
|
716
716
|
}, t2));
|
|
717
717
|
}, flush: () => {
|
|
@@ -728,23 +728,23 @@ async function initializeRecording(e2, n2, i2, o2, s2, r2 = true, a2 = false, l2
|
|
|
728
728
|
}
|
|
729
729
|
const { record: n4 } = await import("@sailfish-rrweb/rrweb-record-only");
|
|
730
730
|
if (Q = n4, await yieldToMain(), l2) {
|
|
731
|
-
const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-
|
|
732
|
-
let
|
|
733
|
-
const
|
|
731
|
+
const { chunkedSnapshot: i3 } = await Promise.resolve().then(() => require("./chunkSerializer-CFHDS9Vi.js")), o3 = n4.mirror;
|
|
732
|
+
let r3 = true;
|
|
733
|
+
const s3 = [];
|
|
734
734
|
n4({ emit(e3) {
|
|
735
|
-
|
|
735
|
+
r3 ? s3.push(e3) : emitWithContext(e3);
|
|
736
736
|
}, maskInputOptions: { text: true }, maskInputFn, ...e2, maskTextClass: e2.maskTextClass ?? J, recordDOM: false });
|
|
737
737
|
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 });
|
|
738
738
|
if (l3) {
|
|
739
739
|
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 });
|
|
740
|
-
for (const e3 of
|
|
741
|
-
|
|
742
|
-
} else console.warn("[Sailfish] chunkSnapshot serialization failed; session continues without initial DOM snapshot"),
|
|
740
|
+
for (const e3 of s3) emitWithContext(e3);
|
|
741
|
+
r3 = false;
|
|
742
|
+
} else console.warn("[Sailfish] chunkSnapshot serialization failed; session continues without initial DOM snapshot"), r3 = false;
|
|
743
743
|
} else n4({ emit(e3) {
|
|
744
744
|
emitWithContext(e3);
|
|
745
745
|
}, maskInputOptions: { text: true }, maskInputFn, ...e2, maskTextClass: e2.maskTextClass ?? J });
|
|
746
746
|
};
|
|
747
|
-
if (
|
|
747
|
+
if (s2) {
|
|
748
748
|
let e3 = false;
|
|
749
749
|
const startOnce = () => {
|
|
750
750
|
e3 || (e3 = true, startHeavyWork());
|
|
@@ -851,21 +851,21 @@ const oe = [(e2) => (function checkNextJs() {
|
|
|
851
851
|
}
|
|
852
852
|
return null;
|
|
853
853
|
}];
|
|
854
|
-
const
|
|
855
|
-
let
|
|
854
|
+
const re = ["jira", "linear", "zendesk"];
|
|
855
|
+
let se = null;
|
|
856
856
|
const ae = /* @__PURE__ */ new Map();
|
|
857
857
|
function getIntegrationData() {
|
|
858
|
-
return
|
|
858
|
+
return se;
|
|
859
859
|
}
|
|
860
860
|
function hasValidIntegration() {
|
|
861
|
-
return null !==
|
|
861
|
+
return null !== se && true === se.installed;
|
|
862
862
|
}
|
|
863
863
|
function resolveIntegration(e2) {
|
|
864
864
|
var _a;
|
|
865
865
|
if ((e2 == null ? void 0 : e2.errors) && e2.errors.length > 0) return console.error("GraphQL errors fetching integrations:", e2.errors), null;
|
|
866
866
|
const t2 = (_a = e2 == null ? void 0 : e2.data) == null ? void 0 : _a.getEngineeringTicketPlatformIntegrationsFromApiKey, n2 = (t2 || []).filter((e3) => {
|
|
867
867
|
var _a2;
|
|
868
|
-
return
|
|
868
|
+
return re.includes(((_a2 = e3.provider) == null ? void 0 : _a2.toLowerCase()) || "") && true === e3.installed;
|
|
869
869
|
});
|
|
870
870
|
if (0 === n2.length) return console.warn("No valid installed integrations found"), null;
|
|
871
871
|
const i2 = n2.find((e3) => {
|
|
@@ -877,9 +877,9 @@ function resolveIntegration(e2) {
|
|
|
877
877
|
async function refreshIntegrationData(e2, t2) {
|
|
878
878
|
try {
|
|
879
879
|
const n2 = resolveIntegration(await fetchEngineeringTicketPlatformIntegrations(e2, t2));
|
|
880
|
-
return
|
|
880
|
+
return se = n2, n2;
|
|
881
881
|
} catch (e3) {
|
|
882
|
-
return console.error("Error refreshing integration data:", e3),
|
|
882
|
+
return console.error("Error refreshing integration data:", e3), se;
|
|
883
883
|
}
|
|
884
884
|
}
|
|
885
885
|
function populateSelectOptions(e2, t2, n2) {
|
|
@@ -914,8 +914,8 @@ function populateSprintOptions(e2, t2, n2) {
|
|
|
914
914
|
}), n2 && (e2.value = n2);
|
|
915
915
|
}
|
|
916
916
|
function getSprintFieldId() {
|
|
917
|
-
if (!(
|
|
918
|
-
const e2 = Array.isArray(
|
|
917
|
+
if (!(se == null ? void 0 : se.fieldConfigurations)) return "customfield_10020";
|
|
918
|
+
const e2 = Array.isArray(se.fieldConfigurations) ? se.fieldConfigurations : [];
|
|
919
919
|
for (const t2 of e2) {
|
|
920
920
|
const e3 = (t2.fields || []).find((e4) => {
|
|
921
921
|
var _a;
|
|
@@ -927,12 +927,12 @@ function getSprintFieldId() {
|
|
|
927
927
|
}
|
|
928
928
|
function updateIssueTypeOptions(e2, t2) {
|
|
929
929
|
var _a;
|
|
930
|
-
if (!(
|
|
930
|
+
if (!(se == null ? void 0 : se.projects) || !t2) {
|
|
931
931
|
e2.innerHTML = "";
|
|
932
932
|
const t3 = document.createElement("option");
|
|
933
933
|
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");
|
|
934
934
|
}
|
|
935
|
-
const n2 =
|
|
935
|
+
const n2 = se.projects.find((e3) => e3.id === t2);
|
|
936
936
|
if (!n2 || !n2.issue_types) {
|
|
937
937
|
e2.innerHTML = "";
|
|
938
938
|
const t3 = document.createElement("option");
|
|
@@ -951,17 +951,17 @@ function updateIssueTypeOptions(e2, t2) {
|
|
|
951
951
|
}), n3 = i2.find((e3) => {
|
|
952
952
|
var _a2;
|
|
953
953
|
return "task" === ((_a2 = e3.name) == null ? void 0 : _a2.toLowerCase());
|
|
954
|
-
}),
|
|
955
|
-
|
|
954
|
+
}), r2 = (t3 == null ? void 0 : t3.id) || (n3 == null ? void 0 : n3.id) || ((_a = i2[0]) == null ? void 0 : _a.id);
|
|
955
|
+
r2 ? (e2.value = r2, e2.style.color = "#000") : (o2.selected = true, e2.style.color = "#9ca3af");
|
|
956
956
|
}
|
|
957
957
|
}
|
|
958
958
|
function getFieldsForProject(e2, t2) {
|
|
959
|
-
if (!(
|
|
960
|
-
const n2 = Array.isArray(
|
|
959
|
+
if (!(se == null ? void 0 : se.fieldConfigurations) || !e2) return [];
|
|
960
|
+
const n2 = Array.isArray(se.fieldConfigurations) ? se.fieldConfigurations.find((n3) => !(n3.project_key !== e2 && String(n3.project_id) !== String(e2) || t2 && String(n3.issue_type_id) !== String(t2))) : se.fieldConfigurations[e2];
|
|
961
961
|
return n2 && n2.fields ? n2.fields : [];
|
|
962
962
|
}
|
|
963
963
|
function getUsers() {
|
|
964
|
-
return (
|
|
964
|
+
return (se == null ? void 0 : se.users) ? se.users : [];
|
|
965
965
|
}
|
|
966
966
|
function getDefaultReporterAccountId() {
|
|
967
967
|
const e2 = getUsers(), t2 = getIdentifiedUser();
|
|
@@ -970,46 +970,74 @@ function getDefaultReporterAccountId() {
|
|
|
970
970
|
const n3 = e2.filter(t3);
|
|
971
971
|
return 1 === n3.length ? n3[0] : null;
|
|
972
972
|
};
|
|
973
|
-
let
|
|
974
|
-
if (!
|
|
973
|
+
let r2 = i2 ? findUnique((e3) => (e3.email || e3.emailAddress || "").toLowerCase().trim() === i2) : null;
|
|
974
|
+
if (!r2 && o2 && (r2 = findUnique((e3) => (e3.name || e3.displayName || "").toLowerCase().trim() === o2)), !r2 && i2) {
|
|
975
975
|
const e3 = i2.split("@")[0];
|
|
976
|
-
e3.length >= 3 && (
|
|
976
|
+
e3.length >= 3 && (r2 = findUnique((t3) => (t3.name || t3.displayName || "").toLowerCase().trim().includes(e3)));
|
|
977
977
|
}
|
|
978
|
-
return
|
|
978
|
+
return r2 && (r2.id || r2.accountId) || null;
|
|
979
|
+
}
|
|
980
|
+
function lastReporterStorageKey() {
|
|
981
|
+
if (!se) return null;
|
|
982
|
+
const e2 = se.primaryCloudId || se.provider || "";
|
|
983
|
+
return e2 ? `sf-veritas:lastReporter:${e2}` : null;
|
|
984
|
+
}
|
|
985
|
+
function getSavedLastReporterAccountId() {
|
|
986
|
+
if ("undefined" == typeof window || "undefined" == typeof localStorage) return null;
|
|
987
|
+
const e2 = lastReporterStorageKey();
|
|
988
|
+
if (!e2) return null;
|
|
989
|
+
try {
|
|
990
|
+
return localStorage.getItem(e2);
|
|
991
|
+
} catch {
|
|
992
|
+
return null;
|
|
993
|
+
}
|
|
994
|
+
}
|
|
995
|
+
function saveLastReporterAccountId(e2) {
|
|
996
|
+
if ("undefined" == typeof window || "undefined" == typeof localStorage) return;
|
|
997
|
+
const t2 = lastReporterStorageKey();
|
|
998
|
+
if (t2 && e2) try {
|
|
999
|
+
localStorage.setItem(t2, e2);
|
|
1000
|
+
} catch {
|
|
1001
|
+
}
|
|
1002
|
+
}
|
|
1003
|
+
function getValidSavedReporterAccountId() {
|
|
1004
|
+
const e2 = getSavedLastReporterAccountId();
|
|
1005
|
+
if (!e2) return null;
|
|
1006
|
+
return getUsers().some((t2) => (t2.accountId || t2.id) === e2 && false !== t2.active) ? e2 : null;
|
|
979
1007
|
}
|
|
980
1008
|
function getProjectsForTeam(e2) {
|
|
981
|
-
if (!
|
|
982
|
-
const t2 =
|
|
1009
|
+
if (!se) return [];
|
|
1010
|
+
const t2 = se.teams && Array.isArray(se.teams) && se.teams.length > 0;
|
|
983
1011
|
if (t2 && e2) {
|
|
984
|
-
const t3 =
|
|
1012
|
+
const t3 = se.teams.find((t4) => t4.id === e2);
|
|
985
1013
|
return (t3 == null ? void 0 : t3.projects) || [];
|
|
986
1014
|
}
|
|
987
|
-
return !t2 &&
|
|
1015
|
+
return !t2 && se.projects ? se.projects : [];
|
|
988
1016
|
}
|
|
989
1017
|
function updateFormWithIntegrationData(e2) {
|
|
990
1018
|
var _a;
|
|
991
|
-
if (!
|
|
992
|
-
const t2 =
|
|
993
|
-
n2 && t2 && (populateSelectOptions(n2,
|
|
1019
|
+
if (!se) return e2;
|
|
1020
|
+
const t2 = se.teams && Array.isArray(se.teams) && se.teams.length > 0, n2 = document.getElementById("sf-eng-ticket-team");
|
|
1021
|
+
n2 && t2 && (populateSelectOptions(n2, se.teams, se.defaultTeam), e2.engTicketTeam ? n2.value = e2.engTicketTeam : e2.engTicketTeam = n2.value);
|
|
994
1022
|
const i2 = document.getElementById("sf-eng-ticket-project");
|
|
995
1023
|
if (i2) {
|
|
996
|
-
populateSelectOptions(i2, t2 ? getProjectsForTeam(e2.engTicketTeam) :
|
|
1024
|
+
populateSelectOptions(i2, t2 ? getProjectsForTeam(e2.engTicketTeam) : se.projects || [], se.defaultProject), e2.engTicketProject ? i2.value = e2.engTicketProject : e2.engTicketProject = i2.value;
|
|
997
1025
|
}
|
|
998
1026
|
const o2 = document.getElementById("sf-eng-ticket-priority");
|
|
999
|
-
o2 && (populatePriorityOptions(o2,
|
|
1000
|
-
const
|
|
1001
|
-
|
|
1027
|
+
o2 && (populatePriorityOptions(o2, se.provider || "", se.defaultPriority), e2.engTicketPriority ? o2.value = String(e2.engTicketPriority) : e2.engTicketPriority = Number(o2.value));
|
|
1028
|
+
const r2 = document.getElementById("sf-eng-ticket-sprint"), s2 = "jira" === ((_a = se.provider) == null ? void 0 : _a.toLowerCase());
|
|
1029
|
+
r2 && s2 && se.sprints && populateSprintOptions(r2, se.sprints, e2.engTicketSprint || void 0);
|
|
1002
1030
|
const a2 = document.getElementById("sf-eng-ticket-type");
|
|
1003
|
-
return a2 &&
|
|
1031
|
+
return a2 && s2 && e2.engTicketProject && (updateIssueTypeOptions(a2, e2.engTicketProject), e2.engTicketIssueType ? (a2.value = e2.engTicketIssueType, a2.style.color = "#000") : a2.value && (e2.engTicketIssueType = a2.value)), e2;
|
|
1004
1032
|
}
|
|
1005
1033
|
const le = Object.freeze(Object.defineProperty({ __proto__: null, fetchIntegrationData: async function fetchIntegrationData(e2, t2) {
|
|
1006
|
-
if (!
|
|
1034
|
+
if (!se) try {
|
|
1007
1035
|
const n2 = await fetchEngineeringTicketPlatformIntegrations(e2, t2);
|
|
1008
|
-
|
|
1036
|
+
se = resolveIntegration(n2);
|
|
1009
1037
|
} catch (e3) {
|
|
1010
|
-
console.error("Error fetching integration data:", e3),
|
|
1038
|
+
console.error("Error fetching integration data:", e3), se = null;
|
|
1011
1039
|
}
|
|
1012
|
-
}, getDefaultReporterAccountId, 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";
|
|
1040
|
+
}, getDefaultReporterAccountId, getFieldsForProject, getIntegrationData, getProjectsForTeam, getSavedLastReporterAccountId, getSprintFieldId, getUsers, getValidSavedReporterAccountId, hasValidIntegration, populatePriorityOptions, populateSelectOptions, populateSprintOptions, refreshIntegrationData, saveLastReporterAccountId, updateFormWithIntegrationData, updateIssueTypeOptions }, Symbol.toStringTag, { value: "Module" })), ce = "sf-create-issue-preference", de = "sf-create-eng-ticket-preference";
|
|
1013
1041
|
function getInitialState() {
|
|
1014
1042
|
const e2 = (function loadUserPreferences() {
|
|
1015
1043
|
return { createIssue: f && "true" === localStorage.getItem(ce), createEngTicket: f && "true" === localStorage.getItem(de) };
|
|
@@ -1058,7 +1086,7 @@ function renderCustomMultiSelect(e2, t2, n2, i2, o2 = false) {
|
|
|
1058
1086
|
}
|
|
1059
1087
|
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: () => {
|
|
1060
1088
|
}, integrationData: null, showEngTicketFieldsDefault: false };
|
|
1061
|
-
let be = null,
|
|
1089
|
+
let be = null, Se = false;
|
|
1062
1090
|
function setupCustomMultiSelectListeners(e2, t2) {
|
|
1063
1091
|
const n2 = document.getElementById(`${e2}-container`), i2 = document.getElementById(`${e2}-dropdown`);
|
|
1064
1092
|
if (!n2 || !i2) return;
|
|
@@ -1075,16 +1103,16 @@ function setupCustomMultiSelectListeners(e2, t2) {
|
|
|
1075
1103
|
</span>`);
|
|
1076
1104
|
}
|
|
1077
1105
|
});
|
|
1078
|
-
const
|
|
1079
|
-
return
|
|
1106
|
+
const r2 = n2.querySelector(".sf-multiselect-chips");
|
|
1107
|
+
return r2 && (r2.innerHTML = o2.join("") || '<span style="color:#9ca3af;">Select...</span>', r2.querySelectorAll(".sf-multiselect-chip-remove").forEach((e4) => {
|
|
1080
1108
|
e4.addEventListener("click", (n3) => {
|
|
1081
1109
|
n3.stopPropagation();
|
|
1082
|
-
const o3 = e4.dataset.value || "",
|
|
1083
|
-
|
|
1084
|
-
const
|
|
1110
|
+
const o3 = e4.dataset.value || "", r3 = i2.querySelector(`.sf-multiselect-option[data-value="${o3}"]`);
|
|
1111
|
+
r3 && (r3.dataset.selected = "false", r3.style.backgroundColor = ""), updateChipsDisplay();
|
|
1112
|
+
const s2 = [];
|
|
1085
1113
|
i2.querySelectorAll(".sf-multiselect-option").forEach((e5) => {
|
|
1086
|
-
"true" === e5.dataset.selected &&
|
|
1087
|
-
}), t2(
|
|
1114
|
+
"true" === e5.dataset.selected && s2.push(e5.dataset.value || "");
|
|
1115
|
+
}), t2(s2);
|
|
1088
1116
|
});
|
|
1089
1117
|
})), e3;
|
|
1090
1118
|
}
|
|
@@ -1093,8 +1121,8 @@ function setupCustomMultiSelectListeners(e2, t2) {
|
|
|
1093
1121
|
n3.stopPropagation();
|
|
1094
1122
|
const i3 = e3, o2 = "true" === i3.dataset.selected;
|
|
1095
1123
|
i3.dataset.selected = String(!o2), i3.style.backgroundColor = o2 ? "" : "#e0f2fe";
|
|
1096
|
-
const
|
|
1097
|
-
t2(
|
|
1124
|
+
const r2 = updateChipsDisplay();
|
|
1125
|
+
t2(r2);
|
|
1098
1126
|
});
|
|
1099
1127
|
}), updateChipsDisplay(), document.addEventListener("click", (e3) => {
|
|
1100
1128
|
const t3 = e3.target;
|
|
@@ -1107,12 +1135,12 @@ function renderDynamicFields(e2, t2) {
|
|
|
1107
1135
|
if (!e2) return void (n2.innerHTML = '<div style="font-size:14px; color:#64748B;">Select a project to see additional fields</div>');
|
|
1108
1136
|
const i2 = getFieldsForProject(e2, t2), o2 = getUsers();
|
|
1109
1137
|
if (!i2 || 0 === i2.length) return void (n2.innerHTML = "");
|
|
1110
|
-
const
|
|
1138
|
+
const r2 = i2.map((e3) => (function renderDynamicField(e4, t3, n3 = []) {
|
|
1111
1139
|
var _a, _b, _c, _d;
|
|
1112
|
-
const i3 = e4.fieldId || e4.key, o3 = e4.name,
|
|
1113
|
-
if (d2.includes(i3) || d2.includes(
|
|
1140
|
+
const i3 = e4.fieldId || e4.key, o3 = e4.name, r3 = (_a = e4.schema) == null ? void 0 : _a.type, s2 = (_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"];
|
|
1141
|
+
if (d2.includes(i3) || d2.includes(s2)) return null;
|
|
1114
1142
|
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;";
|
|
1115
|
-
switch (
|
|
1143
|
+
switch (r3) {
|
|
1116
1144
|
case "string":
|
|
1117
1145
|
return a2 && a2.includes("textarea") ? `
|
|
1118
1146
|
<div>
|
|
@@ -1186,7 +1214,7 @@ function renderDynamicFields(e2, t2) {
|
|
|
1186
1214
|
const e5 = n3.map((e6) => {
|
|
1187
1215
|
const n4 = e6.email ? `${e6.name} (${e6.email})` : e6.name, i4 = t3 === e6.id ? "selected" : "";
|
|
1188
1216
|
return `<option value="${e6.id}" ${i4}>${n4}</option>`;
|
|
1189
|
-
}).join(""),
|
|
1217
|
+
}).join(""), r4 = t3 && n3.some((e6) => e6.id === t3);
|
|
1190
1218
|
return `
|
|
1191
1219
|
<div>
|
|
1192
1220
|
<label for="${i3}" style="display:block; font-size:14px; font-weight:500; margin-bottom:6px;">
|
|
@@ -1196,10 +1224,10 @@ function renderDynamicFields(e2, t2) {
|
|
|
1196
1224
|
id="${i3}"
|
|
1197
1225
|
class="sf-dynamic-field"
|
|
1198
1226
|
data-field-id="${i3}"
|
|
1199
|
-
style="${p2} appearance:none; cursor:pointer; background-color: white; ${
|
|
1227
|
+
style="${p2} appearance:none; cursor:pointer; background-color: white; ${r4 ? "" : "color: #9ca3af;"}"
|
|
1200
1228
|
${l2 ? "required" : ""}
|
|
1201
1229
|
>
|
|
1202
|
-
<option value="" ${
|
|
1230
|
+
<option value="" ${r4 ? "" : "selected"} style="color: #9ca3af;">Select ${o3.toLowerCase()}...</option>
|
|
1203
1231
|
${e5}
|
|
1204
1232
|
</select>
|
|
1205
1233
|
</div>
|
|
@@ -1232,7 +1260,7 @@ function renderDynamicFields(e2, t2) {
|
|
|
1232
1260
|
}
|
|
1233
1261
|
return null;
|
|
1234
1262
|
case "array":
|
|
1235
|
-
return "labels" ===
|
|
1263
|
+
return "labels" === s2 ? null : c2 && c2.length > 0 ? renderCustomMultiSelect(i3, o3, c2, Array.isArray(t3) ? t3 : [], l2) : null;
|
|
1236
1264
|
case "parent":
|
|
1237
1265
|
case "issuelink":
|
|
1238
1266
|
return `
|
|
@@ -1272,7 +1300,7 @@ function renderDynamicFields(e2, t2) {
|
|
|
1272
1300
|
` : null;
|
|
1273
1301
|
}
|
|
1274
1302
|
})(e3, ue.engTicketCustomFields[e3.fieldId || e3.key], o2)).filter(Boolean).join("");
|
|
1275
|
-
n2.innerHTML =
|
|
1303
|
+
n2.innerHTML = r2 || "", i2.forEach((e3) => {
|
|
1276
1304
|
var _a;
|
|
1277
1305
|
const t3 = e3.fieldId || e3.key, n3 = (_a = e3.schema) == null ? void 0 : _a.type, i3 = e3.allowedValues;
|
|
1278
1306
|
"array" === n3 && i3 && i3.length > 0 && setupCustomMultiSelectListeners(t3, (e4) => {
|
|
@@ -1307,7 +1335,7 @@ function getSessionIdSafely() {
|
|
|
1307
1335
|
return ye.resolveSessionId();
|
|
1308
1336
|
}
|
|
1309
1337
|
function openReportIssueModal(e2) {
|
|
1310
|
-
me ? stopRecording() : (
|
|
1338
|
+
me ? stopRecording() : (Se = (e2 == null ? void 0 : e2.showEngTicketFields) ?? ye.showEngTicketFieldsDefault, injectModalHTML(), be && document.body.appendChild(be));
|
|
1311
1339
|
}
|
|
1312
1340
|
function closeModal() {
|
|
1313
1341
|
ye.deactivateIsolation(), document.activeElement instanceof HTMLElement && document.activeElement.blur(), (be == null ? void 0 : be.parentNode) && be.parentNode.removeChild(be), be = null, me || (function resetState() {
|
|
@@ -1329,10 +1357,10 @@ function activateModalIsolation(e2) {
|
|
|
1329
1357
|
n3 && (e2.contains(n3) || (t3.stopImmediatePropagation(), t3.preventDefault(), refocus()));
|
|
1330
1358
|
}, o2 = ["mousedown", "mouseup", "click", "pointerdown", "pointerup", "touchstart", "touchend", "wheel", "keydown", "keyup", "focus", "focusin", "focusout", "blur"];
|
|
1331
1359
|
o2.forEach((e3) => document.addEventListener(e3, quarantine, true));
|
|
1332
|
-
let
|
|
1360
|
+
let r2 = 0, s2 = null;
|
|
1333
1361
|
const a2 = t2 instanceof HTMLTextAreaElement ? t2 : null, refocus = () => {
|
|
1334
|
-
if ((e2.querySelector(":focus") || a2 || t2 || e2).focus({ preventScroll: true }), a2 && document.activeElement === a2 &&
|
|
1335
|
-
a2.setSelectionRange(
|
|
1362
|
+
if ((e2.querySelector(":focus") || a2 || t2 || e2).focus({ preventScroll: true }), a2 && document.activeElement === a2 && s2) try {
|
|
1363
|
+
a2.setSelectionRange(s2.start, s2.end, "none");
|
|
1336
1364
|
} catch {
|
|
1337
1365
|
}
|
|
1338
1366
|
}, selectionInsideModal = () => {
|
|
@@ -1350,12 +1378,12 @@ function activateModalIsolation(e2) {
|
|
|
1350
1378
|
const t3 = document.activeElement, n3 = t3 === document.body || null == t3 || !e2.contains(t3), i3 = selectionInsideModal();
|
|
1351
1379
|
n3 && !i3 ? (l2 += 1, l2 >= 2 && (refocus(), l2 = 0)) : (l2 = 0, (() => {
|
|
1352
1380
|
if (a2 && document.activeElement === a2) try {
|
|
1353
|
-
|
|
1381
|
+
s2 = { start: a2.selectionStart ?? a2.value.length, end: a2.selectionEnd ?? a2.value.length };
|
|
1354
1382
|
} catch {
|
|
1355
1383
|
}
|
|
1356
|
-
})()),
|
|
1384
|
+
})()), r2 = window.requestAnimationFrame(watchdog);
|
|
1357
1385
|
};
|
|
1358
|
-
|
|
1386
|
+
r2 = window.requestAnimationFrame(watchdog);
|
|
1359
1387
|
const onBlurLike = () => {
|
|
1360
1388
|
setTimeout(() => {
|
|
1361
1389
|
const t3 = document.activeElement;
|
|
@@ -1367,7 +1395,7 @@ function activateModalIsolation(e2) {
|
|
|
1367
1395
|
n2.remove(), i2.remove();
|
|
1368
1396
|
} catch {
|
|
1369
1397
|
}
|
|
1370
|
-
o2.forEach((e3) => document.removeEventListener(e3, quarantine, true)), window.removeEventListener("blur", onBlurLike, true), document.removeEventListener("focusout", onBlurLike, true),
|
|
1398
|
+
o2.forEach((e3) => document.removeEventListener(e3, quarantine, true)), window.removeEventListener("blur", onBlurLike, true), document.removeEventListener("focusout", onBlurLike, true), r2 && cancelAnimationFrame(r2);
|
|
1371
1399
|
};
|
|
1372
1400
|
}
|
|
1373
1401
|
function injectModalHTML(e2 = "lookback") {
|
|
@@ -1499,7 +1527,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1499
1527
|
Create an Issue
|
|
1500
1528
|
</label>
|
|
1501
1529
|
|
|
1502
|
-
<label id="sf-create-eng-ticket-label" style="display:${ye.integrationData &&
|
|
1530
|
+
<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;">
|
|
1503
1531
|
<input type="checkbox" id="sf-create-eng-ticket-checkbox" ${ue.createEngTicket ? "checked" : ""}
|
|
1504
1532
|
style="width:16px; height:16px; accent-color:#295DBF; cursor:pointer;">
|
|
1505
1533
|
Create an Eng Ticket
|
|
@@ -1575,8 +1603,8 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1575
1603
|
o2 && o2.addEventListener("change", () => {
|
|
1576
1604
|
"lookback" === ue.mode && (i2.disabled = false, i2.style.opacity = "1", i2.style.cursor = "pointer");
|
|
1577
1605
|
});
|
|
1578
|
-
const
|
|
1579
|
-
|
|
1606
|
+
const r2 = be == null ? void 0 : be.querySelectorAll(".sf-collapsible-header");
|
|
1607
|
+
r2 == null ? void 0 : r2.forEach((e4) => {
|
|
1580
1608
|
e4.addEventListener("click", (e5) => {
|
|
1581
1609
|
const t4 = e5.currentTarget, n3 = t4.dataset.target, i3 = document.getElementById(n3), o3 = t4.querySelector(".sf-chevron");
|
|
1582
1610
|
if (i3 && o3) {
|
|
@@ -1587,21 +1615,21 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1587
1615
|
}
|
|
1588
1616
|
});
|
|
1589
1617
|
});
|
|
1590
|
-
const
|
|
1591
|
-
|
|
1592
|
-
const e4 =
|
|
1618
|
+
const s2 = 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");
|
|
1619
|
+
s2 && s2.addEventListener("change", () => {
|
|
1620
|
+
const e4 = s2.checked;
|
|
1593
1621
|
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"));
|
|
1594
1622
|
});
|
|
1595
1623
|
l2 && l2.addEventListener("change", async () => {
|
|
1596
1624
|
var _a;
|
|
1597
1625
|
const e4 = l2.checked;
|
|
1598
|
-
if (ue.createEngTicket = e4, localStorage.setItem(de, String(e4)), e4 && !ue.createIssue && (ue.createIssue = true, localStorage.setItem(ce, "true"),
|
|
1626
|
+
if (ue.createEngTicket = e4, localStorage.setItem(de, String(e4)), e4 && !ue.createIssue && (ue.createIssue = true, localStorage.setItem(ce, "true"), s2 && (s2.checked = true), a2 && (a2.style.display = "block")), c2 && (c2.style.display = e4 ? "block" : "none"), e4) {
|
|
1599
1627
|
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.");
|
|
1600
1628
|
const e5 = getIntegrationData();
|
|
1601
1629
|
if (e5) {
|
|
1602
1630
|
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()) && ue.engTicketProject && !ue.engTicketCustomFields.reporter) {
|
|
1603
1631
|
if (getFieldsForProject(ue.engTicketProject, ue.engTicketIssueType).find((e6) => "reporter" === e6.fieldId)) {
|
|
1604
|
-
const t5 = getDefaultReporterAccountId();
|
|
1632
|
+
const t5 = getValidSavedReporterAccountId() || getDefaultReporterAccountId();
|
|
1605
1633
|
ue.engTicketCustomFields.reporter = t5 || e5.jiraReporterAccountId || "";
|
|
1606
1634
|
}
|
|
1607
1635
|
}
|
|
@@ -1677,7 +1705,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1677
1705
|
i3 = Date.now(), n3 = i3 - e6;
|
|
1678
1706
|
}
|
|
1679
1707
|
if (ue.createIssue) {
|
|
1680
|
-
const o3 = document.getElementById("sf-issue-name"),
|
|
1708
|
+
const o3 = document.getElementById("sf-issue-name"), r3 = document.getElementById("sf-eng-ticket-team"), s3 = 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 = (r3 == null ? void 0 : r3.value) || "", p2 = (s3 == null ? void 0 : s3.value) || "", f2 = a3 ? Number(a3.value) : 0, g2 = ue.engTicketLabels, m2 = (l3 == null ? void 0 : l3.value) || "", h2 = { ...ue.engTicketCustomFields };
|
|
1681
1709
|
document.querySelectorAll(".sf-dynamic-field").forEach((e6) => {
|
|
1682
1710
|
const t5 = e6, n4 = t5.dataset.fieldId;
|
|
1683
1711
|
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));
|
|
@@ -1687,11 +1715,11 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1687
1715
|
const e6 = getSprintFieldId();
|
|
1688
1716
|
h2[e6] = parseInt(b2, 10);
|
|
1689
1717
|
}
|
|
1690
|
-
closeModal(), (async function createTriageAndIssue(e6, t5, n4, i4, o4,
|
|
1718
|
+
closeModal(), (async function createTriageAndIssue(e6, t5, n4, i4, o4, r4, s4, a4, l4, c4, d4, u3, p3) {
|
|
1691
1719
|
var _a2, _b, _c;
|
|
1692
1720
|
try {
|
|
1693
1721
|
showStatusModal(true);
|
|
1694
|
-
const f3 = await createTriageAndIssueFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4, i4, o4,
|
|
1722
|
+
const f3 = await createTriageAndIssueFromRecorder(ye.apiKey, ye.backendApi, getSessionIdSafely(), e6, t5, n4, i4, o4, r4, s4, a4, l4, c4, d4, u3, p3);
|
|
1695
1723
|
if ((_a2 = f3 == null ? void 0 : f3.errors) == null ? void 0 : _a2.length) {
|
|
1696
1724
|
const e7 = f3.errors.map((e8) => e8.message).join("; ");
|
|
1697
1725
|
return console.error("GraphQL error creating triage and issue:", e7), void showStatusModal(false, null, e7);
|
|
@@ -1711,8 +1739,8 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1711
1739
|
const e7 = o3.errors.map((e8) => e8.message).join("; ");
|
|
1712
1740
|
return console.error("GraphQL error creating triage:", e7), void showStatusModal(false, null, e7);
|
|
1713
1741
|
}
|
|
1714
|
-
const
|
|
1715
|
-
|
|
1742
|
+
const r3 = (_c = (_b = o3 == null ? void 0 : o3.data) == null ? void 0 : _b.createTriageFromRecorder) == null ? void 0 : _c.id;
|
|
1743
|
+
r3 ? showStatusModal(false, { type: "triage", id: r3 }) : (console.error("No Triage ID returned from backend."), showStatusModal(false, null, "No triage was created. Please try again."));
|
|
1716
1744
|
} catch (e7) {
|
|
1717
1745
|
console.error("Error creating triage:", e7), showStatusModal(false, null, "Something went wrong. Please try again.");
|
|
1718
1746
|
}
|
|
@@ -1727,7 +1755,7 @@ function injectModalHTML(e2 = "lookback") {
|
|
|
1727
1755
|
const e4 = generateEngTicketFieldsHTML();
|
|
1728
1756
|
e4 && (t3.innerHTML = e4, initializeEngTicketForm(), bindEngTicketListeners(), updateFormWithIntegrationData(ue), renderDynamicFields(ue.engTicketProject, ue.engTicketIssueType));
|
|
1729
1757
|
}
|
|
1730
|
-
if (
|
|
1758
|
+
if (Se) {
|
|
1731
1759
|
const e4 = document.getElementById("sf-create-eng-ticket-label");
|
|
1732
1760
|
e4 && (e4.style.display = "flex");
|
|
1733
1761
|
}
|
|
@@ -1739,7 +1767,7 @@ function initializeEngTicketForm() {
|
|
|
1739
1767
|
if (e2) {
|
|
1740
1768
|
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()) && ue.engTicketProject && !ue.engTicketCustomFields.reporter) {
|
|
1741
1769
|
if (getFieldsForProject(ue.engTicketProject, ue.engTicketIssueType).find((e3) => "reporter" === e3.fieldId)) {
|
|
1742
|
-
const t2 = getDefaultReporterAccountId();
|
|
1770
|
+
const t2 = getValidSavedReporterAccountId() || getDefaultReporterAccountId();
|
|
1743
1771
|
ue.engTicketCustomFields.reporter = t2 || e2.jiraReporterAccountId || "";
|
|
1744
1772
|
}
|
|
1745
1773
|
}
|
|
@@ -1752,18 +1780,18 @@ function setActiveTab(e2) {
|
|
|
1752
1780
|
"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");
|
|
1753
1781
|
}
|
|
1754
1782
|
function updateModeSpecificUI(e2) {
|
|
1755
|
-
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"),
|
|
1756
|
-
if (t2 && n2 && i2 && o2 &&
|
|
1757
|
-
i2.style.display = "block", a2.style.display = "none",
|
|
1783
|
+
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"), r2 = document.getElementById("sf-recording-timer-display"), s2 = document.getElementById("sf-modal-footer"), a2 = document.getElementById("sf-lookback-container");
|
|
1784
|
+
if (t2 && n2 && i2 && o2 && r2 && s2 && a2) if ("startnow" === e2) {
|
|
1785
|
+
i2.style.display = "block", a2.style.display = "none", s2.style.justifyContent = "space-between", t2.textContent = "I want to reproduce the issue right now.";
|
|
1758
1786
|
const e3 = null !== pe && null !== fe;
|
|
1759
1787
|
if (n2.disabled = !e3, n2.style.opacity = e3 ? "1" : "0.4", n2.style.cursor = e3 ? "pointer" : "not-allowed", pe && fe) {
|
|
1760
1788
|
const e4 = Math.floor((fe - pe) / 1e3), t3 = String(Math.floor(e4 / 60)).padStart(2, "0"), n3 = String(e4 % 60).padStart(2, "0");
|
|
1761
|
-
o2.style.display = "block",
|
|
1789
|
+
o2.style.display = "block", r2.textContent = `${t3}:${n3}`;
|
|
1762
1790
|
} else o2.style.display = "none";
|
|
1763
|
-
} else i2.style.display = "none", o2.style.display = "none", a2.style.display = "block",
|
|
1791
|
+
} else i2.style.display = "none", o2.style.display = "none", a2.style.display = "block", s2.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";
|
|
1764
1792
|
}
|
|
1765
1793
|
function bindEngTicketListeners() {
|
|
1766
|
-
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"),
|
|
1794
|
+
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"), r2 = document.getElementById("sf-eng-ticket-sprint");
|
|
1767
1795
|
e2 && e2.addEventListener("change", () => {
|
|
1768
1796
|
ue.engTicketTeam = e2.value, e2.style.color = e2.value ? "" : "#9ca3af";
|
|
1769
1797
|
const t3 = document.getElementById("sf-eng-ticket-project");
|
|
@@ -1781,13 +1809,13 @@ function bindEngTicketListeners() {
|
|
|
1781
1809
|
const e3 = getIntegrationData();
|
|
1782
1810
|
if (e3 && o2 && (updateIssueTypeOptions(o2, t2.value), ue.engTicketIssueType = o2.value), e3 && "jira" === ((_a = e3.provider) == null ? void 0 : _a.toLowerCase()) && t2.value) {
|
|
1783
1811
|
if (getFieldsForProject(t2.value, ue.engTicketIssueType).find((e4) => "reporter" === e4.fieldId)) {
|
|
1784
|
-
const t3 = getDefaultReporterAccountId();
|
|
1812
|
+
const t3 = getValidSavedReporterAccountId() || getDefaultReporterAccountId();
|
|
1785
1813
|
ue.engTicketCustomFields.reporter = t3 || e3.jiraReporterAccountId || "";
|
|
1786
1814
|
}
|
|
1787
1815
|
}
|
|
1788
1816
|
renderDynamicFields(t2.value, ue.engTicketIssueType);
|
|
1789
|
-
}),
|
|
1790
|
-
ue.engTicketSprint =
|
|
1817
|
+
}), r2 && r2.addEventListener("change", () => {
|
|
1818
|
+
ue.engTicketSprint = r2.value, r2.style.color = r2.value ? "" : "#9ca3af";
|
|
1791
1819
|
}), n2 && n2.addEventListener("change", () => {
|
|
1792
1820
|
ue.engTicketPriority = Number(n2.value);
|
|
1793
1821
|
}), i2 && setupCustomMultiSelectListeners("sf-eng-ticket-labels", (e3) => {
|
|
@@ -1800,18 +1828,18 @@ function bindEngTicketListeners() {
|
|
|
1800
1828
|
ue.engTicketCustomFields = {}, t3 && (ue.engTicketCustomFields.reporter = t3), renderDynamicFields(e3.value, o2.value);
|
|
1801
1829
|
}
|
|
1802
1830
|
});
|
|
1803
|
-
const
|
|
1804
|
-
|
|
1831
|
+
const s2 = document.getElementById("sf-dynamic-fields-container");
|
|
1832
|
+
s2 && (s2.addEventListener("input", (e3) => {
|
|
1805
1833
|
const t3 = e3.target;
|
|
1806
1834
|
if (t3.classList.contains("sf-dynamic-field")) {
|
|
1807
1835
|
const e4 = t3.dataset.fieldId;
|
|
1808
1836
|
e4 && ("checkbox" === t3.type ? ue.engTicketCustomFields[e4] = t3.checked : "number" === t3.type ? ue.engTicketCustomFields[e4] = parseFloat(t3.value) || null : ue.engTicketCustomFields[e4] = t3.value);
|
|
1809
1837
|
}
|
|
1810
|
-
}),
|
|
1838
|
+
}), s2.addEventListener("change", (e3) => {
|
|
1811
1839
|
const t3 = e3.target;
|
|
1812
1840
|
if (t3.classList.contains("sf-dynamic-field")) {
|
|
1813
1841
|
const e4 = t3.dataset.fieldId;
|
|
1814
|
-
if (e4 && (ue.engTicketCustomFields[e4] = t3.value), "SELECT" === t3.tagName) {
|
|
1842
|
+
if (e4 && (ue.engTicketCustomFields[e4] = t3.value, "reporter" === e4 && t3.value && saveLastReporterAccountId(t3.value)), "SELECT" === t3.tagName) {
|
|
1815
1843
|
const e5 = t3;
|
|
1816
1844
|
e5.style.color = e5.value ? "" : "#9ca3af";
|
|
1817
1845
|
}
|
|
@@ -1845,10 +1873,10 @@ async function stopRecording() {
|
|
|
1845
1873
|
i2 && (i2.value = ue.description);
|
|
1846
1874
|
const o2 = document.querySelector('input[value="startnow"]');
|
|
1847
1875
|
o2 && (o2.checked = true);
|
|
1848
|
-
const
|
|
1849
|
-
if (
|
|
1876
|
+
const r2 = document.getElementById("sf-inline-record-chip"), s2 = document.getElementById("sf-inline-record-timer");
|
|
1877
|
+
if (r2 && s2) {
|
|
1850
1878
|
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");
|
|
1851
|
-
|
|
1879
|
+
s2.textContent = `${t3}:${n3}`, s2.style.color = "black", r2.style.display = "flex";
|
|
1852
1880
|
}
|
|
1853
1881
|
const a2 = document.getElementById("sf-issue-submit-btn");
|
|
1854
1882
|
a2.disabled = false, a2.style.opacity = "1", a2.style.cursor = "pointer";
|
|
@@ -1861,10 +1889,10 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1861
1889
|
var _a2, _b;
|
|
1862
1890
|
(_a2 = document.getElementById("sf-report-issue-modal")) == null ? void 0 : _a2.remove(), (_b = document.getElementById("sf-triage-status-modal")) == null ? void 0 : _b.remove();
|
|
1863
1891
|
})();
|
|
1864
|
-
const o2 = !e3 && i2,
|
|
1865
|
-
|
|
1892
|
+
const o2 = !e3 && i2, r2 = n3 ? `${ye.triageBaseUrl}/issues/${n3}?from=inAppReportIssue` : t3 ? `${ye.triageBaseUrl}/triage/${t3}?from=inAppReportIssue` : "", s2 = document.createElement("div");
|
|
1893
|
+
s2.id = "sf-triage-status-modal", Object.assign(s2.style, { position: "fixed", inset: "0", zIndex: "9998", display: "flex", alignItems: "center", justifyContent: "center" });
|
|
1866
1894
|
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>';
|
|
1867
|
-
|
|
1895
|
+
s2.innerHTML = `
|
|
1868
1896
|
<div style="position:fixed; inset:0; background:rgba(0,0,0,0.4); z-index:9998;"></div>
|
|
1869
1897
|
<div id="sf-triage-card"
|
|
1870
1898
|
style="position:relative; background:#fff; padding:24px; border-radius:12px; width:300px; max-width:90%;
|
|
@@ -1905,26 +1933,26 @@ function showStatusModal(e2, t2, n2) {
|
|
|
1905
1933
|
<style>
|
|
1906
1934
|
@keyframes spin { to { transform: rotate(360deg); } }
|
|
1907
1935
|
</style>
|
|
1908
|
-
`, document.body.appendChild(
|
|
1909
|
-
const u2 =
|
|
1936
|
+
`, document.body.appendChild(s2);
|
|
1937
|
+
const u2 = s2.querySelector("#sf-triage-card");
|
|
1910
1938
|
(_a = document.getElementById("sf-triage-modal-close")) == null ? void 0 : _a.addEventListener("click", () => {
|
|
1911
|
-
fadeCardAndRemove(
|
|
1939
|
+
fadeCardAndRemove(s2, u2, 300);
|
|
1912
1940
|
});
|
|
1913
1941
|
const p2 = document.getElementById("sf-copy-triage-link"), f2 = document.getElementById("sf-view-triage-btn");
|
|
1914
1942
|
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", () => {
|
|
1915
|
-
navigator.clipboard.writeText(
|
|
1943
|
+
navigator.clipboard.writeText(r2).then(() => {
|
|
1916
1944
|
const e4 = document.getElementById("sf-copied-status");
|
|
1917
1945
|
e4 && (e4.style.display = "flex");
|
|
1918
1946
|
});
|
|
1919
1947
|
}), f2.disabled = false, f2.addEventListener("click", () => {
|
|
1920
|
-
(t3 || n3) && window.open(
|
|
1921
|
-
}), o2 || setTimeout(() => fadeCardAndRemove(
|
|
1948
|
+
(t3 || n3) && window.open(r2, "_blank");
|
|
1949
|
+
}), o2 || setTimeout(() => fadeCardAndRemove(s2, u2, 300), 1e4));
|
|
1922
1950
|
})(e2, "triage" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, "issue" === (t2 == null ? void 0 : t2.type) ? t2.id : void 0, n2);
|
|
1923
1951
|
}
|
|
1924
1952
|
function fadeCardAndRemove(e2, t2, n2 = 300) {
|
|
1925
1953
|
t2.style.opacity = "0", t2.addEventListener("transitionend", () => e2.remove(), { once: true }), setTimeout(() => e2.remove(), n2 + 100);
|
|
1926
1954
|
}
|
|
1927
|
-
const
|
|
1955
|
+
const ve = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueContext: ye, openReportIssueModal, setupIssueReporting: function setupIssueReporting(e2) {
|
|
1928
1956
|
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) {
|
|
1929
1957
|
const t3 = { ...he };
|
|
1930
1958
|
if (!e3) return t3;
|
|
@@ -1941,23 +1969,23 @@ const Se = Object.freeze(Object.defineProperty({ __proto__: null, ReportIssueCon
|
|
|
1941
1969
|
const n2 = (function isTypingInInput() {
|
|
1942
1970
|
const e4 = document.activeElement;
|
|
1943
1971
|
return e4 instanceof HTMLInputElement || e4 instanceof HTMLTextAreaElement || e4 instanceof HTMLElement && e4.isContentEditable;
|
|
1944
|
-
})(), i2 = e3.key.toLowerCase(), o2 = e3.metaKey || e3.ctrlKey,
|
|
1972
|
+
})(), i2 = e3.key.toLowerCase(), o2 = e3.metaKey || e3.ctrlKey, r2 = !!document.getElementById("sf-report-issue-modal"), s2 = !n2 && (t2.enabled || r2), shortcutUsed = (e4) => i2 === t2[e4].key && o2 === t2[e4].requireCmdCtrl, a2 = r2 ? (e4) => {
|
|
1945
1973
|
setActiveTab(e4), updateModeSpecificUI(e4);
|
|
1946
1974
|
} : injectModalHTML;
|
|
1947
|
-
if (
|
|
1948
|
-
if (
|
|
1949
|
-
if (
|
|
1950
|
-
if (
|
|
1975
|
+
if (s2 && shortcutUsed("openModalExistingMode")) return e3.preventDefault(), void a2("lookback");
|
|
1976
|
+
if (s2 && shortcutUsed("openModalCaptureNewMode")) return e3.preventDefault(), void a2("startnow");
|
|
1977
|
+
if (r2 && !me && shortcutUsed("closeModal")) return e3.preventDefault(), void closeModal();
|
|
1978
|
+
if (r2 && shortcutUsed("submitReport")) {
|
|
1951
1979
|
const t3 = document.getElementById("sf-issue-submit-btn");
|
|
1952
1980
|
return void (t3 && !t3.disabled && (e3.preventDefault(), t3.click()));
|
|
1953
1981
|
}
|
|
1954
1982
|
if (me && i2 === t2.stopRecording.key && o2 === t2.stopRecording.requireCmdCtrl) return e3.preventDefault(), void stopRecording();
|
|
1955
|
-
if (
|
|
1983
|
+
if (r2 && "startnow" === ue.mode && i2 === t2.startRecording.key && o2 === t2.startRecording.requireCmdCtrl && !n2) {
|
|
1956
1984
|
const t3 = document.getElementById("sf-start-recording-btn");
|
|
1957
1985
|
return void (t3 && (e3.preventDefault(), t3.click()));
|
|
1958
1986
|
}
|
|
1959
1987
|
});
|
|
1960
|
-
} }, Symbol.toStringTag, { value: "Module" })),
|
|
1988
|
+
} }, Symbol.toStringTag, { value: "Module" })), we = readDebugFlag(), ke = /* @__PURE__ */ new Map();
|
|
1961
1989
|
function getCachedRegex(e2, t2) {
|
|
1962
1990
|
const n2 = `${e2}|${t2}`;
|
|
1963
1991
|
let i2 = ke.get(n2);
|
|
@@ -1969,8 +1997,8 @@ function maskAuthorizationHeader(e2) {
|
|
|
1969
1997
|
if (!t2) return;
|
|
1970
1998
|
const n2 = e2[t2], i2 = n2.indexOf(" ");
|
|
1971
1999
|
if (-1 !== i2) {
|
|
1972
|
-
const o2 = n2.slice(0, i2 + 1),
|
|
1973
|
-
|
|
2000
|
+
const o2 = n2.slice(0, i2 + 1), r2 = n2.slice(i2 + 1);
|
|
2001
|
+
r2.length > 8 ? e2[t2] = o2 + r2.slice(0, 4) + "*".repeat(r2.length - 8) + r2.slice(-4) : e2[t2] = o2 + "*".repeat(r2.length);
|
|
1974
2002
|
} else n2.length > 8 ? e2[t2] = n2.slice(0, 4) + "*".repeat(n2.length - 8) + n2.slice(-4) : e2[t2] = "*".repeat(n2.length);
|
|
1975
2003
|
}
|
|
1976
2004
|
function trackDomainChangesOnce() {
|
|
@@ -2014,7 +2042,7 @@ function handleVisibilityChange() {
|
|
|
2014
2042
|
const e2 = document.visibilityState, t2 = Date.now();
|
|
2015
2043
|
"visible" === e2 && getOrSetSessionId();
|
|
2016
2044
|
try {
|
|
2017
|
-
sendMessage({ type: "visibilityChange", data: { state: e2, url: window.location.href.split("?")[0], timestamp: t2, ...getUrlAndStoredUuids() } }),
|
|
2045
|
+
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`);
|
|
2018
2046
|
} catch (e3) {
|
|
2019
2047
|
console.warn("[Sailfish] Failed to send visibility change event:", e3);
|
|
2020
2048
|
}
|
|
@@ -2023,9 +2051,9 @@ function handleVisibilityChange() {
|
|
|
2023
2051
|
function clearPageVisitDataFromSessionStorage() {
|
|
2024
2052
|
g && (sessionStorage.removeItem("pageVisitUUID"), sessionStorage.removeItem("prevPageVisitUUID"), sessionStorage.removeItem("tabVisibilityChanged"), sessionStorage.removeItem("tabVisibilityState"), invalidateUrlCache());
|
|
2025
2053
|
}
|
|
2026
|
-
let
|
|
2054
|
+
let Ae = false;
|
|
2027
2055
|
function _ensureModuleSideEffects() {
|
|
2028
|
-
|
|
2056
|
+
Ae || (Ae = true, restoreFuncSpanState(), (function ensureSessionListeners() {
|
|
2029
2057
|
b || (b = true, u && window.addEventListener("beforeunload", () => {
|
|
2030
2058
|
window.name = h + window.name;
|
|
2031
2059
|
}));
|
|
@@ -2036,24 +2064,24 @@ function _ensureModuleSideEffects() {
|
|
|
2036
2064
|
}));
|
|
2037
2065
|
}
|
|
2038
2066
|
function matchParsedUrlAgainstPatterns(e2, t2) {
|
|
2039
|
-
const { hostname: n2, pathname: i2, port: o2 } = e2,
|
|
2067
|
+
const { hostname: n2, pathname: i2, port: o2 } = e2, r2 = n2.startsWith("www.") ? n2.slice(4).toLowerCase() : n2.toLowerCase();
|
|
2040
2068
|
return t2.some((e3) => {
|
|
2041
2069
|
const t3 = String(e3 || "").replace(/^[a-zA-Z]+:\/\//, "");
|
|
2042
|
-
let [n3,
|
|
2070
|
+
let [n3, s2] = t3.split("/", 2), a2 = "";
|
|
2043
2071
|
n3.includes(":") && ([n3, a2] = n3.split(":"));
|
|
2044
|
-
const l2 = getCachedRegex(`^${n3.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`, "i"), c2 =
|
|
2072
|
+
const l2 = getCachedRegex(`^${n3.replace(/\./g, "\\.").replace(/\*/g, ".*")}$`, "i"), c2 = r2.startsWith("www.") ? r2.slice(4) : r2;
|
|
2045
2073
|
if (a2 && "*" !== a2 && o2 !== a2) return false;
|
|
2046
2074
|
if (n3.startsWith("*.")) {
|
|
2047
2075
|
const e4 = n3.slice(2).toLowerCase();
|
|
2048
|
-
if (!(
|
|
2049
|
-
if (
|
|
2050
|
-
return getCachedRegex(`^/${
|
|
2076
|
+
if (!(r2 === e4 || c2 === e4 || r2.endsWith("." + e4))) return false;
|
|
2077
|
+
if (s2) {
|
|
2078
|
+
return getCachedRegex(`^/${s2.replace(/\*/g, ".*").replace(/\/$/, "")}`, "i").test(i2);
|
|
2051
2079
|
}
|
|
2052
2080
|
return true;
|
|
2053
2081
|
}
|
|
2054
|
-
if (!l2.test(c2) && !l2.test(
|
|
2055
|
-
if (
|
|
2056
|
-
return getCachedRegex(`^/${
|
|
2082
|
+
if (!l2.test(c2) && !l2.test(r2)) return false;
|
|
2083
|
+
if (s2) {
|
|
2084
|
+
return getCachedRegex(`^/${s2.replace(/\*/g, ".*").replace(/\/$/, "")}`, "i").test(i2);
|
|
2057
2085
|
}
|
|
2058
2086
|
return true;
|
|
2059
2087
|
});
|
|
@@ -2067,12 +2095,12 @@ function createSkipHeadersPropagationChecker(e2 = [], t2 = []) {
|
|
|
2067
2095
|
} catch {
|
|
2068
2096
|
return true;
|
|
2069
2097
|
}
|
|
2070
|
-
const
|
|
2071
|
-
return !(-1 ===
|
|
2098
|
+
const r2 = o2.pathname.toLowerCase(), s2 = r2.lastIndexOf(".");
|
|
2099
|
+
return !(-1 === s2 || !xe.has(r2.slice(s2))) || (!(!i2 || matchParsedUrlAgainstPatterns(o2, t2)) || !!matchParsedUrlAgainstPatterns(o2, n2));
|
|
2072
2100
|
};
|
|
2073
2101
|
}
|
|
2074
2102
|
function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i2 = []) {
|
|
2075
|
-
const o2 = window.fetch,
|
|
2103
|
+
const o2 = window.fetch, r2 = getOrSetSessionId(), s2 = createSkipHeadersPropagationChecker(e2, i2), a2 = ["text/event-stream", "application/x-ndjson", "application/stream+json", "application/grpc", "application/grpc-web"], l2 = ["application/octet-stream"];
|
|
2076
2104
|
window.fetch = new Proxy(o2, { apply: async (e3, i3, o3) => {
|
|
2077
2105
|
let c2, d2 = o3[0], u2 = o3[1] || {};
|
|
2078
2106
|
if ("string" == typeof d2) c2 = d2;
|
|
@@ -2081,79 +2109,79 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2081
2109
|
if (!(d2 instanceof URL)) return e3.apply(i3, o3);
|
|
2082
2110
|
c2 = d2.href;
|
|
2083
2111
|
}
|
|
2084
|
-
return
|
|
2112
|
+
return s2(c2) ? e3.apply(i3, o3) : (async function injectHeaderWrapper(e4, i4, o4, r3, s3, c3, d3) {
|
|
2085
2113
|
var _a, _b;
|
|
2086
2114
|
if (!c3) return e4.apply(i4, o4);
|
|
2087
2115
|
let u3 = uuidv4();
|
|
2088
|
-
const p2 = getUrlAndStoredUuids(), f2 =
|
|
2116
|
+
const p2 = getUrlAndStoredUuids(), f2 = s3.method || "GET", g2 = Date.now();
|
|
2089
2117
|
let m2, h2 = {}, y2 = null;
|
|
2090
2118
|
try {
|
|
2091
|
-
if (
|
|
2092
|
-
|
|
2119
|
+
if (r3 instanceof Request) {
|
|
2120
|
+
r3.headers.forEach((e5, t3) => {
|
|
2093
2121
|
h2[t3] = e5;
|
|
2094
2122
|
});
|
|
2095
2123
|
try {
|
|
2096
|
-
y2 =
|
|
2124
|
+
y2 = r3.clone();
|
|
2097
2125
|
} catch (e5) {
|
|
2098
2126
|
y2 = null;
|
|
2099
2127
|
}
|
|
2100
|
-
} else
|
|
2128
|
+
} else s3.headers && (s3.headers instanceof Headers ? s3.headers.forEach((e5, t3) => {
|
|
2101
2129
|
h2[t3] = e5;
|
|
2102
|
-
}) : Array.isArray(
|
|
2130
|
+
}) : Array.isArray(s3.headers) ? s3.headers.forEach(([e5, t3]) => {
|
|
2103
2131
|
h2[e5] = t3;
|
|
2104
|
-
}) : h2 = { ...
|
|
2132
|
+
}) : h2 = { ...s3.headers }), m2 = s3.body;
|
|
2105
2133
|
} catch (e5) {
|
|
2106
|
-
|
|
2134
|
+
we && console.warn("[Sailfish] Failed to capture request data:", e5);
|
|
2107
2135
|
}
|
|
2108
2136
|
delete h2[n];
|
|
2109
2137
|
const b2 = getFuncSpanHeader();
|
|
2110
2138
|
b2 && delete h2[b2.name];
|
|
2111
|
-
const
|
|
2112
|
-
h2[n] =
|
|
2139
|
+
const S2 = `${c3}/${p2.page_visit_uuid}/${u3}`;
|
|
2140
|
+
h2[n] = S2, b2 && (h2[b2.name] = b2.value);
|
|
2113
2141
|
maskAuthorizationHeader(h2);
|
|
2114
2142
|
try {
|
|
2115
|
-
let b3 = await (async function injectHeader(e5, t3, i5, o5,
|
|
2143
|
+
let b3 = await (async function injectHeader(e5, t3, i5, o5, r4, s4, a3) {
|
|
2116
2144
|
const l3 = getFuncSpanHeader();
|
|
2117
2145
|
if (i5 instanceof Request) {
|
|
2118
2146
|
const c4 = i5.clone(), d4 = new Headers(c4.headers);
|
|
2119
|
-
d4.set(n, `${
|
|
2147
|
+
d4.set(n, `${r4}/${s4}/${a3}`), l3 && (d4.set(l3.name, l3.value), we && console.log("[Sailfish] Added funcspan header to HTTP Request:", { url: i5.url, header: l3.name }));
|
|
2120
2148
|
const u4 = new Request(c4, { headers: d4 });
|
|
2121
2149
|
return await e5.call(t3, u4, o5);
|
|
2122
2150
|
}
|
|
2123
2151
|
{
|
|
2124
2152
|
const c4 = { ...o5 }, d4 = new Headers(o5.headers || {});
|
|
2125
|
-
return d4.set(n, `${
|
|
2153
|
+
return d4.set(n, `${r4}/${s4}/${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);
|
|
2126
2154
|
}
|
|
2127
|
-
})(e4, i4,
|
|
2128
|
-
Te.includes(b3.status) && (
|
|
2155
|
+
})(e4, i4, r3, s3, c3, p2.page_visit_uuid, u3), S3 = false;
|
|
2156
|
+
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) {
|
|
2129
2157
|
try {
|
|
2130
|
-
let o6 = i5[0],
|
|
2158
|
+
let o6 = i5[0], r4 = i5[1] || {};
|
|
2131
2159
|
if ("string" == typeof o6 || o6 instanceof URL) {
|
|
2132
|
-
const i6 = { ...
|
|
2133
|
-
|
|
2160
|
+
const i6 = { ...r4 }, s4 = new Headers(r4.headers || {});
|
|
2161
|
+
s4.delete(n), i6.headers = s4;
|
|
2134
2162
|
return await e5.call(t3, o6, i6);
|
|
2135
2163
|
}
|
|
2136
2164
|
if (o6 instanceof Request) {
|
|
2137
|
-
const i6 = o6.clone(),
|
|
2138
|
-
|
|
2139
|
-
const a3 = new Request(i6, { headers:
|
|
2140
|
-
return await e5.call(t3, a3,
|
|
2165
|
+
const i6 = o6.clone(), s4 = new Headers(i6.headers);
|
|
2166
|
+
s4.delete(n);
|
|
2167
|
+
const a3 = new Request(i6, { headers: s4 });
|
|
2168
|
+
return await e5.call(t3, a3, r4);
|
|
2141
2169
|
}
|
|
2142
2170
|
return e5.apply(t3, i5);
|
|
2143
2171
|
} catch (e6) {
|
|
2144
|
-
throw
|
|
2172
|
+
throw we && console.log(`Retry without ${n} for ${o5} also failed:`, e6), e6;
|
|
2145
2173
|
}
|
|
2146
|
-
})(e4, i4, o4, d3),
|
|
2147
|
-
const
|
|
2174
|
+
})(e4, i4, o4, d3), S3 = true);
|
|
2175
|
+
const v2 = Date.now(), w2 = b3.status, k2 = b3.ok, x2 = k2 ? "" : `Request Error: ${b3.statusText}`;
|
|
2148
2176
|
let I2 = null;
|
|
2149
2177
|
try {
|
|
2150
2178
|
I2 = {}, b3.headers.forEach((e5, t3) => {
|
|
2151
2179
|
I2[t3] = e5;
|
|
2152
2180
|
});
|
|
2153
2181
|
} catch (e5) {
|
|
2154
|
-
|
|
2182
|
+
we && console.warn("[Sailfish] Failed to capture response headers:", e5), I2 = null;
|
|
2155
2183
|
}
|
|
2156
|
-
const T2 = { type: 27, timestamp:
|
|
2184
|
+
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) => {
|
|
2157
2185
|
T2.data.response_body = e5, y2 ? y2.text().then((e6) => {
|
|
2158
2186
|
T2.data.request_body = e6, sendEvent(T2);
|
|
2159
2187
|
}, () => {
|
|
@@ -2176,18 +2204,18 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2176
2204
|
(async function readStreamPrefix(e5, t3, n2) {
|
|
2177
2205
|
const i5 = e5.body;
|
|
2178
2206
|
if (!i5) return null;
|
|
2179
|
-
const o5 = i5.getReader(),
|
|
2207
|
+
const o5 = i5.getReader(), r4 = new TextDecoder(), s4 = [];
|
|
2180
2208
|
let a3 = 0;
|
|
2181
2209
|
const readWithLimit = async () => {
|
|
2182
2210
|
try {
|
|
2183
2211
|
for (; a3 < t3; ) {
|
|
2184
2212
|
const { done: e6, value: t4 } = await o5.read();
|
|
2185
2213
|
if (e6) break;
|
|
2186
|
-
a3 += t4.byteLength,
|
|
2214
|
+
a3 += t4.byteLength, s4.push(r4.decode(t4, { stream: true }));
|
|
2187
2215
|
}
|
|
2188
|
-
return
|
|
2216
|
+
return s4.push(r4.decode()), s4.join("");
|
|
2189
2217
|
} catch {
|
|
2190
|
-
return
|
|
2218
|
+
return s4.length > 0 ? s4.join("") : null;
|
|
2191
2219
|
} finally {
|
|
2192
2220
|
try {
|
|
2193
2221
|
o5.cancel();
|
|
@@ -2201,7 +2229,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2201
2229
|
o5.cancel();
|
|
2202
2230
|
} catch {
|
|
2203
2231
|
}
|
|
2204
|
-
e6(
|
|
2232
|
+
e6(s4.length > 0 ? s4.join("") : null);
|
|
2205
2233
|
}, n2))]);
|
|
2206
2234
|
} catch {
|
|
2207
2235
|
try {
|
|
@@ -2228,7 +2256,7 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2228
2256
|
}
|
|
2229
2257
|
return b3;
|
|
2230
2258
|
} catch (t3) {
|
|
2231
|
-
const n2 = Date.now(),
|
|
2259
|
+
const n2 = Date.now(), r4 = false, s4 = ((_a = t3.response) == null ? void 0 : _a.status) || 500, a3 = t3.message || "Fetch request failed";
|
|
2232
2260
|
if (t3 instanceof TypeError && ((_b = t3 == null ? void 0 : t3.message) == null ? void 0 : _b.toLowerCase().includes(Ee.toLowerCase()))) return e4.apply(i4, o4);
|
|
2233
2261
|
let l3 = m2;
|
|
2234
2262
|
if (y2) try {
|
|
@@ -2236,12 +2264,12 @@ function setupFetchInterceptor(e2 = [], t2 = { captureStreamingResponseBody: tru
|
|
|
2236
2264
|
} catch {
|
|
2237
2265
|
l3 = null;
|
|
2238
2266
|
}
|
|
2239
|
-
throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code:
|
|
2267
|
+
throw sendEvent({ type: 27, timestamp: n2, sessionId: c3, data: { request_id: u3, session_id: c3, timestamp_start: g2, timestamp_end: n2, response_code: s4, success: r4, error: a3, method: f2, url: d3, request_headers: h2, request_body: l3, response_body: null }, ...p2 }), t3;
|
|
2240
2268
|
}
|
|
2241
|
-
})(e3, i3, o3, d2, u2,
|
|
2269
|
+
})(e3, i3, o3, d2, u2, r2, c2);
|
|
2242
2270
|
} });
|
|
2243
2271
|
}
|
|
2244
|
-
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = ["*"], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion:
|
|
2272
|
+
async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-service.sailfishqa.com", domainsToPropagateHeaderTo: i2 = ["*"], domainsToNotPropagateHeaderTo: o2 = [], serviceVersion: r2, serviceIdentifier: s2, 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, capturePerformanceMetrics: v2 = true, maskTextClass: w2, library: k2, headlessRecording: x2 = false }) {
|
|
2245
2273
|
var _a, _b;
|
|
2246
2274
|
if (!x2 && (function isHeadlessOrLighthouse() {
|
|
2247
2275
|
try {
|
|
@@ -2258,16 +2286,16 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2258
2286
|
if (E2.sessionId = T2, E2.apiKey = e2, E2.backendApi = t2, E2.serviceAdditionalMetadata = l2, E2.initialized && E2.sessionId === T2 && E2.ws && 1 === E2.ws.readyState) return void trackDomainChangesOnce();
|
|
2259
2287
|
const C2 = { captureStreamingResponseBody: d2, captureResponseBodyMaxMb: u2, captureStreamPrefixKb: p2, captureStreamTimeoutMs: f2 };
|
|
2260
2288
|
sessionStorage.getItem("pageVisitUUID") || (sessionStorage.setItem("pageVisitUUID", uuidv4()), invalidateUrlCache()), E2.xhrPatched || (!(function setupXMLHttpRequestInterceptor(e3 = [], t3 = { captureStreamingResponseBody: true, captureResponseBodyMaxMb: 10, captureStreamPrefixKb: 64, captureStreamTimeoutMs: 1e4 }, i3 = []) {
|
|
2261
|
-
const o3 = XMLHttpRequest.prototype.open,
|
|
2289
|
+
const o3 = XMLHttpRequest.prototype.open, r3 = XMLHttpRequest.prototype.send, s3 = XMLHttpRequest.prototype.setRequestHeader, a3 = getOrSetSessionId(), l3 = createSkipHeadersPropagationChecker(e3, i3);
|
|
2262
2290
|
XMLHttpRequest.prototype.setRequestHeader = function(e4, t4) {
|
|
2263
|
-
return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4,
|
|
2291
|
+
return this._capturedRequestHeaders || (this._capturedRequestHeaders = {}), this._capturedRequestHeaders[e4] = t4, s3.call(this, e4, t4);
|
|
2264
2292
|
}, XMLHttpRequest.prototype.open = function(e4, t4, ...n2) {
|
|
2265
2293
|
return this._requestUrl = "string" == typeof t4 && t4.length > 0 ? t4 : null, this._requestMethod = e4, this._capturedRequestHeaders = {}, o3.apply(this, [e4, t4, ...n2]);
|
|
2266
2294
|
}, XMLHttpRequest.prototype.send = function(...e4) {
|
|
2267
2295
|
const i4 = this._requestUrl;
|
|
2268
|
-
if (!i4) return
|
|
2269
|
-
if (l3(i4)) return
|
|
2270
|
-
const o4 = sessionStorage.getItem("pageVisitUUID"),
|
|
2296
|
+
if (!i4) return r3.apply(this, e4);
|
|
2297
|
+
if (l3(i4)) return r3.apply(this, e4);
|
|
2298
|
+
const o4 = sessionStorage.getItem("pageVisitUUID"), s4 = uuidv4(), c3 = `${a3}/${o4}/${s4}`;
|
|
2271
2299
|
try {
|
|
2272
2300
|
this.setRequestHeader(n, c3);
|
|
2273
2301
|
} catch (e5) {
|
|
@@ -2275,19 +2303,19 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2275
2303
|
}
|
|
2276
2304
|
const d3 = getFuncSpanHeader();
|
|
2277
2305
|
if (d3) try {
|
|
2278
|
-
this.setRequestHeader(d3.name, d3.value),
|
|
2306
|
+
this.setRequestHeader(d3.name, d3.value), we && console.log("[Sailfish] Added funcspan header to XMLHttpRequest:", { url: i4, header: d3.name });
|
|
2279
2307
|
} catch (e5) {
|
|
2280
|
-
|
|
2308
|
+
we && console.warn(`[Sailfish] Could not set funcspan header for ${i4}`, e5);
|
|
2281
2309
|
}
|
|
2282
2310
|
const u3 = Date.now();
|
|
2283
2311
|
let p3 = false;
|
|
2284
2312
|
const f3 = e4[0], g2 = { ...this._capturedRequestHeaders };
|
|
2285
2313
|
maskAuthorizationHeader(g2);
|
|
2286
|
-
const emitFinished = (e5, t4, n2, o5,
|
|
2314
|
+
const emitFinished = (e5, t4, n2, o5, r4) => {
|
|
2287
2315
|
if (p3) return;
|
|
2288
2316
|
p3 = true;
|
|
2289
2317
|
const l4 = Date.now();
|
|
2290
|
-
sendEvent({ type: 27, timestamp: l4, sessionId: a3, data: { request_id:
|
|
2318
|
+
sendEvent({ type: 27, timestamp: l4, sessionId: a3, data: { request_id: s4, 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: r4, response_body: o5 }, ...getUrlAndStoredUuids() });
|
|
2291
2319
|
};
|
|
2292
2320
|
return this.addEventListener("load", () => {
|
|
2293
2321
|
const e5 = this.status || 0;
|
|
@@ -2310,7 +2338,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2310
2338
|
2 === t4.length && (i5[t4[0]] = t4[1]);
|
|
2311
2339
|
});
|
|
2312
2340
|
} catch (e6) {
|
|
2313
|
-
|
|
2341
|
+
we && console.warn("[Sailfish] Failed to capture XHR response headers:", e6), i5 = null;
|
|
2314
2342
|
}
|
|
2315
2343
|
if (e5 >= 200 && e5 < 300) emitFinished(true, e5, "", n2, i5);
|
|
2316
2344
|
else {
|
|
@@ -2320,7 +2348,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2320
2348
|
}, { once: true }), this.addEventListener("error", () => {
|
|
2321
2349
|
const e5 = this.status || 0, t4 = 0 === e5 ? "Network or CORS failure" : this.statusText || `Error ${e5}`;
|
|
2322
2350
|
emitFinished(false, e5, t4);
|
|
2323
|
-
}, { once: true }),
|
|
2351
|
+
}, { once: true }), r3.apply(this, e4);
|
|
2324
2352
|
};
|
|
2325
2353
|
})(o2, C2, i2), E2.xhrPatched = true), E2.fetchPatched || (setupFetchInterceptor(o2, C2, i2), E2.fetchPatched = true), await yieldToMain(), E2.domEventsInit || (initializeDomContentEvents(T2), E2.domEventsInit = true), await yieldToMain(), E2.consoleInit || (initializeConsolePlugin(Le, T2), E2.consoleInit = true), await yieldToMain(), E2.errorInit || (!(function initializeErrorInterceptor() {
|
|
2326
2354
|
window.addEventListener("error", (e3) => {
|
|
@@ -2328,13 +2356,13 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2328
2356
|
}), window.addEventListener("unhandledrejection", (e3) => {
|
|
2329
2357
|
captureError(e3.reason, true);
|
|
2330
2358
|
});
|
|
2331
|
-
})(), E2.errorInit = true), await yieldToMain(), !E2.perfInit &&
|
|
2359
|
+
})(), E2.errorInit = true), await yieldToMain(), !E2.perfInit && v2 && (initializePerformancePlugin(T2), E2.perfInit = true), await yieldToMain(), _ensureModuleSideEffects(), (function storeCredentialsAndConnection({ apiKey: e3, backendApi: t3 }) {
|
|
2332
2360
|
g && (sessionStorage.setItem("sailfishApiKey", e3), sessionStorage.setItem("sailfishBackendApi", t3));
|
|
2333
2361
|
})({ apiKey: e2, backendApi: t2 }), !isFunctionSpanTrackingEnabled() || E2.ws && 1 === E2.ws.readyState || fetchFunctionSpanTrackingEnabled(e2, t2).then((e3) => {
|
|
2334
2362
|
var _a2;
|
|
2335
|
-
((_a2 = e3.data) == null ? void 0 : _a2.isFunctionSpanTrackingEnabledFromApiKey) ?? false ?
|
|
2363
|
+
((_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"));
|
|
2336
2364
|
}).catch((e3) => {
|
|
2337
|
-
|
|
2365
|
+
we && console.warn("[Sailfish] Failed to validate function span tracking status with backend:", e3);
|
|
2338
2366
|
}), E2.sentDoNotPropagateOnce || (sendDomainsToNotPropagateHeaderTo(e2, [...o2, ...Ie], t2).catch((e3) => console.error("Failed to send domains to not propagate header to:", e3)), E2.sentDoNotPropagateOnce = true), (async function gatherAndCacheDeviceInfo() {
|
|
2339
2367
|
sendMessage({ type: "deviceInfo", data: { deviceInfo: { language: navigator.language, userAgent: navigator.userAgent } } });
|
|
2340
2368
|
})(), c2 && fetchAndSendIp(T2);
|
|
@@ -2356,7 +2384,7 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2356
2384
|
if ("string" == typeof e3 && e3) return e3;
|
|
2357
2385
|
} catch {
|
|
2358
2386
|
}
|
|
2359
|
-
})(), i3 =
|
|
2387
|
+
})(), i3 = s2 ?? "", o3 = r2 ?? "", c3 = k2 ?? "JS/TS", d3 = (function getMapUuidFromWindow() {
|
|
2360
2388
|
try {
|
|
2361
2389
|
const e3 = window;
|
|
2362
2390
|
if (e3 && "string" == typeof e3.sfMapUuid && e3.sfMapUuid) return e3.sfMapUuid;
|
|
@@ -2376,15 +2404,15 @@ async function startRecording({ apiKey: e2, backendApi: t2 = "https://api-servic
|
|
|
2376
2404
|
return { framework: i4[0] ?? null, additionalFrameworks: i4.slice(1), serviceRole: "frontend" };
|
|
2377
2405
|
})(), f3 = { ...u3, serviceRole: p3.serviceRole, ...null !== p3.framework && { framework: p3.framework }, ...p3.additionalFrameworks.length > 0 && { additionalFrameworks: p3.additionalFrameworks } };
|
|
2378
2406
|
await yieldToMain();
|
|
2379
|
-
const [g2, h3] = await Promise.all([fetchCaptureSettings(e2, t2), startRecordingSession(e2, T2, t2, i3, o3, d3, n2, c3, f3)]), y3 = { ...Fe, ...(_a = g2.data) == null ? void 0 : _a.captureSettingsFromApiKey, enableFiberTracking: m2, ...void 0 !==
|
|
2407
|
+
const [g2, h3] = await Promise.all([fetchCaptureSettings(e2, t2), startRecordingSession(e2, T2, t2, i3, o3, d3, n2, c3, f3)]), y3 = { ...Fe, ...(_a = g2.data) == null ? void 0 : _a.captureSettingsFromApiKey, enableFiberTracking: m2, ...void 0 !== w2 ? { maskTextClass: w2 } : {} };
|
|
2380
2408
|
if (E2.ws && 1 === E2.ws.readyState) return;
|
|
2381
2409
|
if ((_b = h3.data) == null ? void 0 : _b.startRecordingSession) {
|
|
2382
2410
|
const n3 = (l2 == null ? void 0 : l2.env) || (l2 == null ? void 0 : l2.environment);
|
|
2383
2411
|
await yieldToMain();
|
|
2384
|
-
const i4 = await initializeRecording(y3, t2, e2, T2, n3, I2,
|
|
2412
|
+
const i4 = await initializeRecording(y3, t2, e2, T2, n3, I2, S2, b2 ?? false);
|
|
2385
2413
|
E2.ws = i4, E2.initialized = true, trackDomainChangesOnce(), E2.sentMapUuidOnce || (!(function sendMapUuidIfAvailable(e3 = "", t3 = "") {
|
|
2386
2414
|
window.sfMapUuid && sendMessage({ type: "mapUuid", data: { mapUuid: window.sfMapUuid, serviceIdentifier: e3, serviceVersion: t3 } });
|
|
2387
|
-
})(
|
|
2415
|
+
})(s2, r2), E2.sentMapUuidOnce = true);
|
|
2388
2416
|
} else console.error("Failed to start recording session:", h3.errors || h3);
|
|
2389
2417
|
} catch (e3) {
|
|
2390
2418
|
console.error("Error starting recording:", e3);
|
|
@@ -2402,14 +2430,14 @@ exports.DEFAULT_CAPTURE_SETTINGS = Fe, exports.DEFAULT_CONSOLE_RECORDING_SETTING
|
|
|
2402
2430
|
return clearPageVisitDataFromSessionStorage(), t2.initialized && t2.sessionId === n2 && t2.ws && 1 === t2.ws.readyState ? void 0 : (t2.initPromise || (t2.initPromise = (async () => {
|
|
2403
2431
|
try {
|
|
2404
2432
|
if (t2.hasLoggedInitOnce || (console.log("Initializing Sailfish Recorder (first run) …"), t2.hasLoggedInitOnce = true), await startRecording(e2), !t2.issueReportingInit) {
|
|
2405
|
-
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData:
|
|
2406
|
-
let
|
|
2433
|
+
const n3 = e2.backendApi ?? "https://api-service.sailfishqa.com", [{ setupIssueReporting: i2 }, { fetchIntegrationData: o2, getIntegrationData: r2 }] = await Promise.all([Promise.resolve().then(() => ve), Promise.resolve().then(() => le)]);
|
|
2434
|
+
let s2 = null;
|
|
2407
2435
|
try {
|
|
2408
|
-
await o2(e2.apiKey, n3),
|
|
2436
|
+
await o2(e2.apiKey, n3), s2 = r2();
|
|
2409
2437
|
} catch (e3) {
|
|
2410
2438
|
console.warn("[Sailfish] Failed to fetch integration data for issue reporting:", e3);
|
|
2411
2439
|
}
|
|
2412
|
-
i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData:
|
|
2440
|
+
i2({ apiKey: e2.apiKey, backendApi: n3, getSessionId: () => getOrSetSessionId(), shortcuts: e2.reportIssueShortcuts, customBaseUrl: e2.customBaseUrl, integrationData: s2, showEngTicketFieldsInReportIssueModalDefault: e2.showEngTicketFieldsInReportIssueModalDefault }), t2.issueReportingInit = true;
|
|
2413
2441
|
}
|
|
2414
2442
|
} catch (e3) {
|
|
2415
2443
|
console.warn("[Sailfish] Recorder initialization failed:", e3);
|