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