@sailfish-ai/recorder 1.0.0-beta-14 → 1.0.0-beta-2
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/recording.js +5 -33
- package/dist/sailfish-recorder.es.js +554 -54
- package/dist/sailfish-recorder.umd.js +554 -54
- package/dist/types/recording.d.ts +1 -1
- package/dist/websocket.js +1 -1
- package/package.json +1 -1
- package/README.md +0 -1
|
@@ -2,34 +2,34 @@
|
|
|
2
2
|
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.SailfishRecorder = {}));
|
|
3
3
|
})(this, function(exports2) {
|
|
4
4
|
"use strict";
|
|
5
|
-
var byteToHex = [];
|
|
6
|
-
for (var i = 0; i < 256; ++i) {
|
|
7
|
-
byteToHex.push((i + 256).toString(16).slice(1));
|
|
5
|
+
var byteToHex$1 = [];
|
|
6
|
+
for (var i$2 = 0; i$2 < 256; ++i$2) {
|
|
7
|
+
byteToHex$1.push((i$2 + 256).toString(16).slice(1));
|
|
8
8
|
}
|
|
9
9
|
function unsafeStringify(arr, offset = 0) {
|
|
10
|
-
return (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
10
|
+
return (byteToHex$1[arr[offset + 0]] + byteToHex$1[arr[offset + 1]] + byteToHex$1[arr[offset + 2]] + byteToHex$1[arr[offset + 3]] + "-" + byteToHex$1[arr[offset + 4]] + byteToHex$1[arr[offset + 5]] + "-" + byteToHex$1[arr[offset + 6]] + byteToHex$1[arr[offset + 7]] + "-" + byteToHex$1[arr[offset + 8]] + byteToHex$1[arr[offset + 9]] + "-" + byteToHex$1[arr[offset + 10]] + byteToHex$1[arr[offset + 11]] + byteToHex$1[arr[offset + 12]] + byteToHex$1[arr[offset + 13]] + byteToHex$1[arr[offset + 14]] + byteToHex$1[arr[offset + 15]]).toLowerCase();
|
|
11
11
|
}
|
|
12
|
-
var getRandomValues;
|
|
13
|
-
var rnds8 = new Uint8Array(16);
|
|
14
|
-
function rng() {
|
|
15
|
-
if (!getRandomValues) {
|
|
16
|
-
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
17
|
-
if (!getRandomValues) {
|
|
12
|
+
var getRandomValues$1;
|
|
13
|
+
var rnds8$1 = new Uint8Array(16);
|
|
14
|
+
function rng$1() {
|
|
15
|
+
if (!getRandomValues$1) {
|
|
16
|
+
getRandomValues$1 = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto);
|
|
17
|
+
if (!getRandomValues$1) {
|
|
18
18
|
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
19
19
|
}
|
|
20
20
|
}
|
|
21
|
-
return getRandomValues(rnds8);
|
|
21
|
+
return getRandomValues$1(rnds8$1);
|
|
22
22
|
}
|
|
23
23
|
var randomUUID = typeof crypto !== "undefined" && crypto.randomUUID && crypto.randomUUID.bind(crypto);
|
|
24
24
|
const native = {
|
|
25
25
|
randomUUID
|
|
26
26
|
};
|
|
27
|
-
function v4(options, buf, offset) {
|
|
27
|
+
function v4$1(options, buf, offset) {
|
|
28
28
|
if (native.randomUUID && !buf && !options) {
|
|
29
29
|
return native.randomUUID();
|
|
30
30
|
}
|
|
31
31
|
options = options || {};
|
|
32
|
-
var rnds = options.random || (options.rng || rng)();
|
|
32
|
+
var rnds = options.random || (options.rng || rng$1)();
|
|
33
33
|
rnds[6] = rnds[6] & 15 | 64;
|
|
34
34
|
rnds[8] = rnds[8] & 63 | 128;
|
|
35
35
|
return unsafeStringify(rnds);
|
|
@@ -4944,7 +4944,7 @@
|
|
|
4944
4944
|
);
|
|
4945
4945
|
return () => hookSetter$1(target, key, original || {}, true);
|
|
4946
4946
|
}
|
|
4947
|
-
function patch$
|
|
4947
|
+
function patch$2(source, name, replacement) {
|
|
4948
4948
|
try {
|
|
4949
4949
|
if (!(name in source)) {
|
|
4950
4950
|
return () => {
|
|
@@ -6786,7 +6786,7 @@
|
|
|
6786
6786
|
});
|
|
6787
6787
|
return fontFace;
|
|
6788
6788
|
};
|
|
6789
|
-
const restoreHandler = patch$
|
|
6789
|
+
const restoreHandler = patch$2(
|
|
6790
6790
|
doc.fonts,
|
|
6791
6791
|
"add",
|
|
6792
6792
|
function(original) {
|
|
@@ -6846,7 +6846,7 @@
|
|
|
6846
6846
|
const win = doc.defaultView;
|
|
6847
6847
|
if (!win || !win.customElements) return () => {
|
|
6848
6848
|
};
|
|
6849
|
-
const restoreHandler = patch$
|
|
6849
|
+
const restoreHandler = patch$2(
|
|
6850
6850
|
win.customElements,
|
|
6851
6851
|
"define",
|
|
6852
6852
|
function(original) {
|
|
@@ -7204,7 +7204,7 @@
|
|
|
7204
7204
|
if (typeof win.CanvasRenderingContext2D.prototype[prop] !== "function") {
|
|
7205
7205
|
continue;
|
|
7206
7206
|
}
|
|
7207
|
-
const restoreHandler = patch$
|
|
7207
|
+
const restoreHandler = patch$2(
|
|
7208
7208
|
win.CanvasRenderingContext2D.prototype,
|
|
7209
7209
|
prop,
|
|
7210
7210
|
function(original) {
|
|
@@ -7252,7 +7252,7 @@
|
|
|
7252
7252
|
function initCanvasContextObserver(win, blockClass, blockSelector, setPreserveDrawingBufferToTrue) {
|
|
7253
7253
|
const handlers = [];
|
|
7254
7254
|
try {
|
|
7255
|
-
const restoreHandler = patch$
|
|
7255
|
+
const restoreHandler = patch$2(
|
|
7256
7256
|
win.HTMLCanvasElement.prototype,
|
|
7257
7257
|
"getContext",
|
|
7258
7258
|
function(original) {
|
|
@@ -7304,7 +7304,7 @@
|
|
|
7304
7304
|
if (typeof prototype[prop] !== "function") {
|
|
7305
7305
|
continue;
|
|
7306
7306
|
}
|
|
7307
|
-
const restoreHandler = patch$
|
|
7307
|
+
const restoreHandler = patch$2(
|
|
7308
7308
|
prototype,
|
|
7309
7309
|
prop,
|
|
7310
7310
|
function(original) {
|
|
@@ -7673,7 +7673,7 @@
|
|
|
7673
7673
|
patchAttachShadow(element, doc) {
|
|
7674
7674
|
const manager = this;
|
|
7675
7675
|
this.restoreHandlers.push(
|
|
7676
|
-
patch$
|
|
7676
|
+
patch$2(
|
|
7677
7677
|
element.prototype,
|
|
7678
7678
|
"attachShadow",
|
|
7679
7679
|
function(original) {
|
|
@@ -11712,7 +11712,7 @@
|
|
|
11712
11712
|
let LazyResult22$1 = lazyResult$2;
|
|
11713
11713
|
let Container22$1 = container$2;
|
|
11714
11714
|
let Processor22$1 = processor$2;
|
|
11715
|
-
let stringify$
|
|
11715
|
+
let stringify$8 = stringify_1$2;
|
|
11716
11716
|
let fromJSON$3 = fromJSON_1$2;
|
|
11717
11717
|
let Document222$1 = document$1$1;
|
|
11718
11718
|
let Warning22$1 = warning$2;
|
|
@@ -11762,7 +11762,7 @@
|
|
|
11762
11762
|
};
|
|
11763
11763
|
return creator;
|
|
11764
11764
|
};
|
|
11765
|
-
postcss$4.stringify = stringify$
|
|
11765
|
+
postcss$4.stringify = stringify$8;
|
|
11766
11766
|
postcss$4.parse = parse$6;
|
|
11767
11767
|
postcss$4.fromJSON = fromJSON$3;
|
|
11768
11768
|
postcss$4.list = list$4;
|
|
@@ -15535,7 +15535,7 @@
|
|
|
15535
15535
|
);
|
|
15536
15536
|
return () => hookSetter(target, key, original || {}, true);
|
|
15537
15537
|
}
|
|
15538
|
-
function patch(source, name, replacement) {
|
|
15538
|
+
function patch$1(source, name, replacement) {
|
|
15539
15539
|
try {
|
|
15540
15540
|
if (!(name in source)) {
|
|
15541
15541
|
return () => {
|
|
@@ -15855,7 +15855,7 @@
|
|
|
15855
15855
|
return nowTimestamp;
|
|
15856
15856
|
},
|
|
15857
15857
|
on,
|
|
15858
|
-
patch,
|
|
15858
|
+
patch: patch$1,
|
|
15859
15859
|
polyfill: polyfill$1,
|
|
15860
15860
|
queueToResolveTrees,
|
|
15861
15861
|
shadowHostInDom,
|
|
@@ -19661,7 +19661,7 @@
|
|
|
19661
19661
|
}
|
|
19662
19662
|
return false;
|
|
19663
19663
|
}
|
|
19664
|
-
function stringify(obj, stringifyOptions) {
|
|
19664
|
+
function stringify$7(obj, stringifyOptions) {
|
|
19665
19665
|
const options = {
|
|
19666
19666
|
numOfKeysLimit: 50,
|
|
19667
19667
|
depthOfLimit: 4
|
|
@@ -19785,7 +19785,7 @@
|
|
|
19785
19785
|
const trace = ErrorStackParser.parse(error).map(
|
|
19786
19786
|
(stackFrame) => stackFrame.toString()
|
|
19787
19787
|
);
|
|
19788
|
-
const payload = [stringify(message, logOptions.stringifyOptions)];
|
|
19788
|
+
const payload = [stringify$7(message, logOptions.stringifyOptions)];
|
|
19789
19789
|
cb({
|
|
19790
19790
|
level: "error",
|
|
19791
19791
|
trace,
|
|
@@ -19802,7 +19802,7 @@
|
|
|
19802
19802
|
if (event.reason instanceof Error) {
|
|
19803
19803
|
error = event.reason;
|
|
19804
19804
|
payload = [
|
|
19805
|
-
stringify(
|
|
19805
|
+
stringify$7(
|
|
19806
19806
|
`Uncaught (in promise) ${error.name}: ${error.message}`,
|
|
19807
19807
|
logOptions.stringifyOptions
|
|
19808
19808
|
)
|
|
@@ -19810,8 +19810,8 @@
|
|
|
19810
19810
|
} else {
|
|
19811
19811
|
error = new Error();
|
|
19812
19812
|
payload = [
|
|
19813
|
-
stringify("Uncaught (in promise)", logOptions.stringifyOptions),
|
|
19814
|
-
stringify(event.reason, logOptions.stringifyOptions)
|
|
19813
|
+
stringify$7("Uncaught (in promise)", logOptions.stringifyOptions),
|
|
19814
|
+
stringify$7(event.reason, logOptions.stringifyOptions)
|
|
19815
19815
|
];
|
|
19816
19816
|
}
|
|
19817
19817
|
const trace = ErrorStackParser.parse(error).map(
|
|
@@ -19856,7 +19856,7 @@
|
|
|
19856
19856
|
const trace = ErrorStackParser.parse(new Error()).map((stackFrame) => stackFrame.toString()).splice(1);
|
|
19857
19857
|
const argsForPayload = level === "assert" ? args.slice(1) : args;
|
|
19858
19858
|
const payload = argsForPayload.map(
|
|
19859
|
-
(s) => stringify(s, logOptions.stringifyOptions)
|
|
19859
|
+
(s) => stringify$7(s, logOptions.stringifyOptions)
|
|
19860
19860
|
);
|
|
19861
19861
|
logCount++;
|
|
19862
19862
|
if (logCount < logOptions.lengthThreshold) {
|
|
@@ -19870,7 +19870,7 @@
|
|
|
19870
19870
|
level: "warn",
|
|
19871
19871
|
trace: [],
|
|
19872
19872
|
payload: [
|
|
19873
|
-
stringify("The number of log records reached the threshold.")
|
|
19873
|
+
stringify$7("The number of log records reached the threshold.")
|
|
19874
19874
|
]
|
|
19875
19875
|
});
|
|
19876
19876
|
}
|
|
@@ -19890,6 +19890,524 @@
|
|
|
19890
19890
|
observer: initLogObserver,
|
|
19891
19891
|
options
|
|
19892
19892
|
});
|
|
19893
|
+
var getRandomValues;
|
|
19894
|
+
var rnds8 = new Uint8Array(16);
|
|
19895
|
+
function rng() {
|
|
19896
|
+
if (!getRandomValues) {
|
|
19897
|
+
getRandomValues = typeof crypto !== "undefined" && crypto.getRandomValues && crypto.getRandomValues.bind(crypto) || typeof msCrypto !== "undefined" && typeof msCrypto.getRandomValues === "function" && msCrypto.getRandomValues.bind(msCrypto);
|
|
19898
|
+
if (!getRandomValues) {
|
|
19899
|
+
throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");
|
|
19900
|
+
}
|
|
19901
|
+
}
|
|
19902
|
+
return getRandomValues(rnds8);
|
|
19903
|
+
}
|
|
19904
|
+
const REGEX = /^(?:[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}|00000000-0000-0000-0000-000000000000)$/i;
|
|
19905
|
+
function validate(uuid) {
|
|
19906
|
+
return typeof uuid === "string" && REGEX.test(uuid);
|
|
19907
|
+
}
|
|
19908
|
+
var byteToHex = [];
|
|
19909
|
+
for (var i = 0; i < 256; ++i) {
|
|
19910
|
+
byteToHex.push((i + 256).toString(16).substr(1));
|
|
19911
|
+
}
|
|
19912
|
+
function stringify(arr) {
|
|
19913
|
+
var offset = arguments.length > 1 && arguments[1] !== void 0 ? arguments[1] : 0;
|
|
19914
|
+
var uuid = (byteToHex[arr[offset + 0]] + byteToHex[arr[offset + 1]] + byteToHex[arr[offset + 2]] + byteToHex[arr[offset + 3]] + "-" + byteToHex[arr[offset + 4]] + byteToHex[arr[offset + 5]] + "-" + byteToHex[arr[offset + 6]] + byteToHex[arr[offset + 7]] + "-" + byteToHex[arr[offset + 8]] + byteToHex[arr[offset + 9]] + "-" + byteToHex[arr[offset + 10]] + byteToHex[arr[offset + 11]] + byteToHex[arr[offset + 12]] + byteToHex[arr[offset + 13]] + byteToHex[arr[offset + 14]] + byteToHex[arr[offset + 15]]).toLowerCase();
|
|
19915
|
+
if (!validate(uuid)) {
|
|
19916
|
+
throw TypeError("Stringified UUID is invalid");
|
|
19917
|
+
}
|
|
19918
|
+
return uuid;
|
|
19919
|
+
}
|
|
19920
|
+
function v4(options, buf, offset) {
|
|
19921
|
+
options = options || {};
|
|
19922
|
+
var rnds = options.random || (options.rng || rng)();
|
|
19923
|
+
rnds[6] = rnds[6] & 15 | 64;
|
|
19924
|
+
rnds[8] = rnds[8] & 63 | 128;
|
|
19925
|
+
return stringify(rnds);
|
|
19926
|
+
}
|
|
19927
|
+
function findLast(array, predicate) {
|
|
19928
|
+
const length = array.length;
|
|
19929
|
+
for (let i2 = length - 1; i2 >= 0; i2 -= 1) {
|
|
19930
|
+
if (predicate(array[i2])) {
|
|
19931
|
+
return array[i2];
|
|
19932
|
+
}
|
|
19933
|
+
}
|
|
19934
|
+
}
|
|
19935
|
+
function patch(source, name, replacement) {
|
|
19936
|
+
try {
|
|
19937
|
+
if (!(name in source)) {
|
|
19938
|
+
return () => {
|
|
19939
|
+
};
|
|
19940
|
+
}
|
|
19941
|
+
const original = source[name];
|
|
19942
|
+
const wrapped = replacement(original);
|
|
19943
|
+
if (typeof wrapped === "function") {
|
|
19944
|
+
wrapped.prototype = wrapped.prototype || {};
|
|
19945
|
+
Object.defineProperties(wrapped, {
|
|
19946
|
+
__rrweb_original__: {
|
|
19947
|
+
enumerable: false,
|
|
19948
|
+
value: original
|
|
19949
|
+
}
|
|
19950
|
+
});
|
|
19951
|
+
}
|
|
19952
|
+
source[name] = wrapped;
|
|
19953
|
+
return () => {
|
|
19954
|
+
source[name] = original;
|
|
19955
|
+
};
|
|
19956
|
+
} catch {
|
|
19957
|
+
return () => {
|
|
19958
|
+
};
|
|
19959
|
+
}
|
|
19960
|
+
}
|
|
19961
|
+
const defaultNetworkOptions = {
|
|
19962
|
+
initiatorTypes: [
|
|
19963
|
+
"audio",
|
|
19964
|
+
"beacon",
|
|
19965
|
+
"body",
|
|
19966
|
+
"css",
|
|
19967
|
+
"early-hint",
|
|
19968
|
+
"embed",
|
|
19969
|
+
"fetch",
|
|
19970
|
+
"frame",
|
|
19971
|
+
"iframe",
|
|
19972
|
+
"icon",
|
|
19973
|
+
"image",
|
|
19974
|
+
"img",
|
|
19975
|
+
"input",
|
|
19976
|
+
"link",
|
|
19977
|
+
"navigation",
|
|
19978
|
+
"object",
|
|
19979
|
+
"ping",
|
|
19980
|
+
"script",
|
|
19981
|
+
"track",
|
|
19982
|
+
"video",
|
|
19983
|
+
"xmlhttprequest"
|
|
19984
|
+
],
|
|
19985
|
+
ignoreRequestFn: () => false,
|
|
19986
|
+
recordHeaders: false,
|
|
19987
|
+
recordBody: false,
|
|
19988
|
+
recordInitialRequests: false
|
|
19989
|
+
};
|
|
19990
|
+
const isNavigationTiming = (entry) => entry.entryType === "navigation";
|
|
19991
|
+
const isResourceTiming = (entry) => entry.entryType === "resource";
|
|
19992
|
+
let requestId = `sfui-${v4()}`;
|
|
19993
|
+
function updateRequestId(newId) {
|
|
19994
|
+
requestId = newId;
|
|
19995
|
+
console.error(`X-SF3-RID updated to ${newId}`);
|
|
19996
|
+
}
|
|
19997
|
+
function initPerformanceObserver(cb, win, options) {
|
|
19998
|
+
if (options.recordInitialRequests) {
|
|
19999
|
+
const initialPerformanceEntries = win.performance.getEntries().filter(
|
|
20000
|
+
(entry) => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(
|
|
20001
|
+
entry.initiatorType
|
|
20002
|
+
)
|
|
20003
|
+
);
|
|
20004
|
+
cb({
|
|
20005
|
+
requests: initialPerformanceEntries.map((entry) => ({
|
|
20006
|
+
url: entry.name,
|
|
20007
|
+
initiatorType: entry.initiatorType,
|
|
20008
|
+
status: "responseStatus" in entry ? entry.responseStatus : void 0,
|
|
20009
|
+
startTime: Math.round(entry.startTime),
|
|
20010
|
+
endTime: Math.round(entry.responseEnd)
|
|
20011
|
+
})),
|
|
20012
|
+
isInitial: true
|
|
20013
|
+
});
|
|
20014
|
+
}
|
|
20015
|
+
const observer = new win.PerformanceObserver((entries) => {
|
|
20016
|
+
const performanceEntries = entries.getEntries().filter(
|
|
20017
|
+
(entry) => isNavigationTiming(entry) || isResourceTiming(entry) && options.initiatorTypes.includes(
|
|
20018
|
+
entry.initiatorType
|
|
20019
|
+
) && entry.initiatorType !== "xmlhttprequest" && entry.initiatorType !== "fetch"
|
|
20020
|
+
);
|
|
20021
|
+
cb({
|
|
20022
|
+
requests: performanceEntries.map((entry) => ({
|
|
20023
|
+
url: entry.name,
|
|
20024
|
+
initiatorType: entry.initiatorType,
|
|
20025
|
+
status: "responseStatus" in entry ? entry.responseStatus : void 0,
|
|
20026
|
+
startTime: Math.round(entry.startTime),
|
|
20027
|
+
endTime: Math.round(entry.responseEnd)
|
|
20028
|
+
}))
|
|
20029
|
+
});
|
|
20030
|
+
});
|
|
20031
|
+
observer.observe({ entryTypes: ["navigation", "resource"] });
|
|
20032
|
+
return () => {
|
|
20033
|
+
observer.disconnect();
|
|
20034
|
+
};
|
|
20035
|
+
}
|
|
20036
|
+
function shouldRecordHeaders(type, recordHeaders, headers, ignoredHeaders) {
|
|
20037
|
+
if (!recordHeaders) {
|
|
20038
|
+
return false;
|
|
20039
|
+
}
|
|
20040
|
+
if (typeof recordHeaders === "boolean") {
|
|
20041
|
+
if (!recordHeaders) return false;
|
|
20042
|
+
} else if (!recordHeaders[type]) {
|
|
20043
|
+
return false;
|
|
20044
|
+
}
|
|
20045
|
+
const typeSpecificIgnoredHeaders = ignoredHeaders ? ignoredHeaders[type] : [];
|
|
20046
|
+
const effectiveHeaders = {};
|
|
20047
|
+
Object.keys(headers).forEach((header) => {
|
|
20048
|
+
if (typeSpecificIgnoredHeaders && typeSpecificIgnoredHeaders.includes(header.toLowerCase())) {
|
|
20049
|
+
effectiveHeaders[header] = headers[header];
|
|
20050
|
+
}
|
|
20051
|
+
});
|
|
20052
|
+
return Object.keys(effectiveHeaders).length > 0;
|
|
20053
|
+
}
|
|
20054
|
+
function filterHeaders(type, headers, ignoredHeaders) {
|
|
20055
|
+
const filteredHeaders = {};
|
|
20056
|
+
const toIgnore = ignoredHeaders ? ignoredHeaders[type] : [];
|
|
20057
|
+
Object.keys(headers).forEach((header) => {
|
|
20058
|
+
if (!toIgnore.includes(header.toLowerCase())) {
|
|
20059
|
+
filteredHeaders[header] = headers[header];
|
|
20060
|
+
}
|
|
20061
|
+
});
|
|
20062
|
+
return filteredHeaders;
|
|
20063
|
+
}
|
|
20064
|
+
function shouldRecordBody(type, recordBody, headers, ignoreBodyParts) {
|
|
20065
|
+
function matchesContentType(contentTypes) {
|
|
20066
|
+
const contentTypeHeader = Object.keys(headers).find(
|
|
20067
|
+
(key) => key.toLowerCase() === "content-type"
|
|
20068
|
+
);
|
|
20069
|
+
const contentType = contentTypeHeader && headers[contentTypeHeader];
|
|
20070
|
+
return contentTypes.some((ct) => contentType == null ? void 0 : contentType.includes(ct));
|
|
20071
|
+
}
|
|
20072
|
+
if (!recordBody) return false;
|
|
20073
|
+
if (typeof recordBody === "boolean") return true;
|
|
20074
|
+
if (Array.isArray(recordBody)) return matchesContentType(recordBody);
|
|
20075
|
+
const recordBodyType = recordBody[type];
|
|
20076
|
+
if (typeof recordBodyType === "boolean") return recordBodyType;
|
|
20077
|
+
return matchesContentType(recordBodyType);
|
|
20078
|
+
}
|
|
20079
|
+
function getRecordedBody(body, type, ignoreBodyParts) {
|
|
20080
|
+
if (!body || typeof body !== "string") {
|
|
20081
|
+
return body;
|
|
20082
|
+
}
|
|
20083
|
+
try {
|
|
20084
|
+
const data = JSON.parse(body);
|
|
20085
|
+
const ignoredParts = ignoreBodyParts ? ignoreBodyParts[type] : [];
|
|
20086
|
+
const removeNestedProperty = (obj, path) => {
|
|
20087
|
+
const parts = path.split(".");
|
|
20088
|
+
const last = parts.pop();
|
|
20089
|
+
const lastObj = parts.reduce((o, key) => o[key] = o[key] || {}, obj);
|
|
20090
|
+
if (last !== void 0) {
|
|
20091
|
+
delete lastObj[last];
|
|
20092
|
+
}
|
|
20093
|
+
};
|
|
20094
|
+
ignoredParts.forEach((path) => {
|
|
20095
|
+
removeNestedProperty(data, path);
|
|
20096
|
+
});
|
|
20097
|
+
return JSON.stringify(data);
|
|
20098
|
+
} catch (error) {
|
|
20099
|
+
return body;
|
|
20100
|
+
}
|
|
20101
|
+
}
|
|
20102
|
+
async function getRequestPerformanceEntry(win, initiatorType, url, after, before, attempt = 0) {
|
|
20103
|
+
if (attempt > 10) {
|
|
20104
|
+
throw new Error("Cannot find performance entry");
|
|
20105
|
+
}
|
|
20106
|
+
const urlPerformanceEntries = win.performance.getEntriesByName(
|
|
20107
|
+
url
|
|
20108
|
+
);
|
|
20109
|
+
const performanceEntry = findLast(
|
|
20110
|
+
urlPerformanceEntries,
|
|
20111
|
+
(entry) => isResourceTiming(entry) && entry.initiatorType === initiatorType && (!after || entry.startTime >= after) && (!before || entry.startTime <= before)
|
|
20112
|
+
);
|
|
20113
|
+
if (!performanceEntry) {
|
|
20114
|
+
await new Promise((resolve2) => setTimeout(resolve2, 50 * attempt));
|
|
20115
|
+
return getRequestPerformanceEntry(
|
|
20116
|
+
win,
|
|
20117
|
+
initiatorType,
|
|
20118
|
+
url,
|
|
20119
|
+
after,
|
|
20120
|
+
before,
|
|
20121
|
+
attempt + 1
|
|
20122
|
+
);
|
|
20123
|
+
}
|
|
20124
|
+
return performanceEntry;
|
|
20125
|
+
}
|
|
20126
|
+
function initXhrObserver(cb, win, options) {
|
|
20127
|
+
if (!options.initiatorTypes.includes("xmlhttprequest")) {
|
|
20128
|
+
return () => {
|
|
20129
|
+
};
|
|
20130
|
+
}
|
|
20131
|
+
const restorePatch = patch(
|
|
20132
|
+
win.XMLHttpRequest.prototype,
|
|
20133
|
+
"open",
|
|
20134
|
+
(originalOpen) => {
|
|
20135
|
+
return function(method, url, async = true, username, password) {
|
|
20136
|
+
const xhr = this;
|
|
20137
|
+
const req = new Request(url);
|
|
20138
|
+
const networkRequest = {};
|
|
20139
|
+
let after;
|
|
20140
|
+
let before;
|
|
20141
|
+
const requestHeaders = {};
|
|
20142
|
+
const originalSetRequestHeader = xhr.setRequestHeader.bind(xhr);
|
|
20143
|
+
xhr.setRequestHeader = (header, value) => {
|
|
20144
|
+
requestHeaders[header] = value;
|
|
20145
|
+
return originalSetRequestHeader(header, value);
|
|
20146
|
+
};
|
|
20147
|
+
xhr.setRequestHeader("X-SF3-RID", requestId);
|
|
20148
|
+
const recordRequestHeaders = shouldRecordHeaders(
|
|
20149
|
+
"request",
|
|
20150
|
+
options.recordHeaders,
|
|
20151
|
+
requestHeaders,
|
|
20152
|
+
options.ignoreHeaders
|
|
20153
|
+
);
|
|
20154
|
+
if (recordRequestHeaders) {
|
|
20155
|
+
networkRequest.requestHeaders = filterHeaders(
|
|
20156
|
+
"request",
|
|
20157
|
+
requestHeaders,
|
|
20158
|
+
options.ignoreHeaders
|
|
20159
|
+
);
|
|
20160
|
+
}
|
|
20161
|
+
const originalSend = xhr.send.bind(xhr);
|
|
20162
|
+
xhr.send = (body) => {
|
|
20163
|
+
if (shouldRecordBody(
|
|
20164
|
+
"request",
|
|
20165
|
+
options.recordBody,
|
|
20166
|
+
requestHeaders,
|
|
20167
|
+
options.ignoreBodyParts
|
|
20168
|
+
)) {
|
|
20169
|
+
if (body === void 0 || body === null) {
|
|
20170
|
+
networkRequest.requestBody = null;
|
|
20171
|
+
} else {
|
|
20172
|
+
networkRequest.requestBody = getRecordedBody(
|
|
20173
|
+
body,
|
|
20174
|
+
"request",
|
|
20175
|
+
options.ignoreBodyParts
|
|
20176
|
+
);
|
|
20177
|
+
}
|
|
20178
|
+
}
|
|
20179
|
+
after = win.performance.now();
|
|
20180
|
+
return originalSend(body);
|
|
20181
|
+
};
|
|
20182
|
+
xhr.addEventListener("readystatechange", () => {
|
|
20183
|
+
if (xhr.readyState !== xhr.DONE) {
|
|
20184
|
+
return;
|
|
20185
|
+
}
|
|
20186
|
+
before = win.performance.now();
|
|
20187
|
+
const responseHeaders = {};
|
|
20188
|
+
const rawHeaders = xhr.getAllResponseHeaders();
|
|
20189
|
+
const headers = rawHeaders.trim().split(/[\r\n]+/);
|
|
20190
|
+
headers.forEach((line) => {
|
|
20191
|
+
const parts = line.split(": ");
|
|
20192
|
+
const header = parts.shift();
|
|
20193
|
+
const value = parts.join(": ");
|
|
20194
|
+
if (header) {
|
|
20195
|
+
responseHeaders[header] = value;
|
|
20196
|
+
}
|
|
20197
|
+
if (header === "X-SF3-RID" && value !== requestId) {
|
|
20198
|
+
updateRequestId(value);
|
|
20199
|
+
}
|
|
20200
|
+
});
|
|
20201
|
+
const recordResponseHeaders = shouldRecordHeaders(
|
|
20202
|
+
"response",
|
|
20203
|
+
options.recordHeaders,
|
|
20204
|
+
responseHeaders,
|
|
20205
|
+
options.ignoreHeaders
|
|
20206
|
+
);
|
|
20207
|
+
if (recordResponseHeaders) {
|
|
20208
|
+
networkRequest.responseHeaders = filterHeaders(
|
|
20209
|
+
"response",
|
|
20210
|
+
responseHeaders,
|
|
20211
|
+
options.ignoreHeaders
|
|
20212
|
+
);
|
|
20213
|
+
}
|
|
20214
|
+
if (shouldRecordBody(
|
|
20215
|
+
"response",
|
|
20216
|
+
options.recordBody,
|
|
20217
|
+
responseHeaders,
|
|
20218
|
+
options.ignoreBodyParts
|
|
20219
|
+
)) {
|
|
20220
|
+
if (xhr.response === void 0 || xhr.response === null) {
|
|
20221
|
+
networkRequest.responseBody = null;
|
|
20222
|
+
} else {
|
|
20223
|
+
networkRequest.responseBody = getRecordedBody(
|
|
20224
|
+
xhr.response,
|
|
20225
|
+
"response",
|
|
20226
|
+
options.ignoreBodyParts
|
|
20227
|
+
);
|
|
20228
|
+
}
|
|
20229
|
+
}
|
|
20230
|
+
getRequestPerformanceEntry(
|
|
20231
|
+
win,
|
|
20232
|
+
"xmlhttprequest",
|
|
20233
|
+
req.url,
|
|
20234
|
+
after,
|
|
20235
|
+
before
|
|
20236
|
+
).then((entry) => {
|
|
20237
|
+
const request = {
|
|
20238
|
+
url: entry.name,
|
|
20239
|
+
method: req.method,
|
|
20240
|
+
initiatorType: entry.initiatorType,
|
|
20241
|
+
status: xhr.status,
|
|
20242
|
+
startTime: Math.round(entry.startTime),
|
|
20243
|
+
endTime: Math.round(entry.responseEnd),
|
|
20244
|
+
requestHeaders: networkRequest.requestHeaders,
|
|
20245
|
+
requestBody: networkRequest.requestBody,
|
|
20246
|
+
responseHeaders: networkRequest.responseHeaders,
|
|
20247
|
+
responseBody: networkRequest.responseBody
|
|
20248
|
+
};
|
|
20249
|
+
cb({ requests: [request] });
|
|
20250
|
+
}).catch(() => {
|
|
20251
|
+
});
|
|
20252
|
+
});
|
|
20253
|
+
originalOpen.call(xhr, method, url, async, username, password);
|
|
20254
|
+
};
|
|
20255
|
+
}
|
|
20256
|
+
);
|
|
20257
|
+
return () => {
|
|
20258
|
+
restorePatch();
|
|
20259
|
+
};
|
|
20260
|
+
}
|
|
20261
|
+
function initFetchObserver(cb, win, options) {
|
|
20262
|
+
if (!options.initiatorTypes.includes("fetch")) {
|
|
20263
|
+
return () => {
|
|
20264
|
+
};
|
|
20265
|
+
}
|
|
20266
|
+
const restorePatch = patch(win, "fetch", (originalFetch) => {
|
|
20267
|
+
return async function(url, init) {
|
|
20268
|
+
const req = new Request(url, {
|
|
20269
|
+
...init,
|
|
20270
|
+
headers: {
|
|
20271
|
+
...init == null ? void 0 : init.headers,
|
|
20272
|
+
"X-SF3-RID": requestId
|
|
20273
|
+
}
|
|
20274
|
+
});
|
|
20275
|
+
let res;
|
|
20276
|
+
const networkRequest = {};
|
|
20277
|
+
let after;
|
|
20278
|
+
let before;
|
|
20279
|
+
try {
|
|
20280
|
+
const requestHeaders = {};
|
|
20281
|
+
req.headers.forEach((value, header) => {
|
|
20282
|
+
requestHeaders[header] = value;
|
|
20283
|
+
});
|
|
20284
|
+
const recordRequestHeaders = shouldRecordHeaders(
|
|
20285
|
+
"request",
|
|
20286
|
+
options.recordHeaders,
|
|
20287
|
+
requestHeaders,
|
|
20288
|
+
options.ignoreHeaders
|
|
20289
|
+
);
|
|
20290
|
+
if (recordRequestHeaders) {
|
|
20291
|
+
networkRequest.requestHeaders = filterHeaders(
|
|
20292
|
+
"request",
|
|
20293
|
+
requestHeaders,
|
|
20294
|
+
options.ignoreHeaders
|
|
20295
|
+
);
|
|
20296
|
+
}
|
|
20297
|
+
if (shouldRecordBody(
|
|
20298
|
+
"request",
|
|
20299
|
+
options.recordBody,
|
|
20300
|
+
requestHeaders,
|
|
20301
|
+
options.ignoreBodyParts
|
|
20302
|
+
)) {
|
|
20303
|
+
if (req.body === void 0 || req.body === null) {
|
|
20304
|
+
networkRequest.requestBody = null;
|
|
20305
|
+
} else {
|
|
20306
|
+
networkRequest.requestBody = getRecordedBody(
|
|
20307
|
+
await req.clone().text(),
|
|
20308
|
+
"request",
|
|
20309
|
+
options.ignoreBodyParts
|
|
20310
|
+
);
|
|
20311
|
+
}
|
|
20312
|
+
}
|
|
20313
|
+
after = win.performance.now();
|
|
20314
|
+
res = await originalFetch(req);
|
|
20315
|
+
before = win.performance.now();
|
|
20316
|
+
const responseHeaders = {};
|
|
20317
|
+
res.headers.forEach((value, header) => {
|
|
20318
|
+
responseHeaders[header] = value;
|
|
20319
|
+
if (header === "X-SF3-RID" && value !== requestId) {
|
|
20320
|
+
updateRequestId(value);
|
|
20321
|
+
}
|
|
20322
|
+
});
|
|
20323
|
+
const recordResponseHeaders = shouldRecordHeaders(
|
|
20324
|
+
"response",
|
|
20325
|
+
options.recordHeaders,
|
|
20326
|
+
responseHeaders,
|
|
20327
|
+
options.ignoreHeaders
|
|
20328
|
+
);
|
|
20329
|
+
if (recordResponseHeaders) {
|
|
20330
|
+
networkRequest.responseHeaders = filterHeaders(
|
|
20331
|
+
"response",
|
|
20332
|
+
responseHeaders,
|
|
20333
|
+
options.ignoreHeaders
|
|
20334
|
+
);
|
|
20335
|
+
}
|
|
20336
|
+
if (shouldRecordBody(
|
|
20337
|
+
"response",
|
|
20338
|
+
options.recordBody,
|
|
20339
|
+
responseHeaders,
|
|
20340
|
+
options.ignoreBodyParts
|
|
20341
|
+
)) {
|
|
20342
|
+
let body;
|
|
20343
|
+
try {
|
|
20344
|
+
body = await res.clone().text();
|
|
20345
|
+
} catch {
|
|
20346
|
+
}
|
|
20347
|
+
if (res.body === void 0 || res.body === null) {
|
|
20348
|
+
networkRequest.responseBody = null;
|
|
20349
|
+
} else {
|
|
20350
|
+
networkRequest.responseBody = getRecordedBody(
|
|
20351
|
+
await res.clone().text(),
|
|
20352
|
+
"response",
|
|
20353
|
+
options.ignoreBodyParts
|
|
20354
|
+
);
|
|
20355
|
+
}
|
|
20356
|
+
}
|
|
20357
|
+
return res;
|
|
20358
|
+
} finally {
|
|
20359
|
+
getRequestPerformanceEntry(win, "fetch", req.url, after, before).then((entry) => {
|
|
20360
|
+
const request = {
|
|
20361
|
+
url: entry.name,
|
|
20362
|
+
method: req.method,
|
|
20363
|
+
initiatorType: entry.initiatorType,
|
|
20364
|
+
status: res == null ? void 0 : res.status,
|
|
20365
|
+
startTime: Math.round(entry.startTime),
|
|
20366
|
+
endTime: Math.round(entry.responseEnd),
|
|
20367
|
+
requestHeaders: networkRequest.requestHeaders,
|
|
20368
|
+
requestBody: networkRequest.requestBody,
|
|
20369
|
+
responseHeaders: networkRequest.responseHeaders,
|
|
20370
|
+
responseBody: networkRequest.responseBody
|
|
20371
|
+
};
|
|
20372
|
+
cb({ requests: [request] });
|
|
20373
|
+
}).catch(() => {
|
|
20374
|
+
});
|
|
20375
|
+
}
|
|
20376
|
+
};
|
|
20377
|
+
});
|
|
20378
|
+
return () => {
|
|
20379
|
+
restorePatch();
|
|
20380
|
+
};
|
|
20381
|
+
}
|
|
20382
|
+
function initNetworkObserver(callback, win, options) {
|
|
20383
|
+
if (!("performance" in win)) {
|
|
20384
|
+
return () => {
|
|
20385
|
+
};
|
|
20386
|
+
}
|
|
20387
|
+
const networkOptions = options ? Object.assign({}, defaultNetworkOptions, options) : defaultNetworkOptions;
|
|
20388
|
+
const cb = (data) => {
|
|
20389
|
+
const requests = data.requests.filter(
|
|
20390
|
+
(request) => !networkOptions.ignoreRequestFn(request)
|
|
20391
|
+
);
|
|
20392
|
+
if (requests.length > 0 || data.isInitial) {
|
|
20393
|
+
callback({ ...data, requests });
|
|
20394
|
+
}
|
|
20395
|
+
};
|
|
20396
|
+
const performanceObserver = initPerformanceObserver(cb, win, networkOptions);
|
|
20397
|
+
const xhrObserver = initXhrObserver(cb, win, networkOptions);
|
|
20398
|
+
const fetchObserver = initFetchObserver(cb, win, networkOptions);
|
|
20399
|
+
return () => {
|
|
20400
|
+
performanceObserver();
|
|
20401
|
+
xhrObserver();
|
|
20402
|
+
fetchObserver();
|
|
20403
|
+
};
|
|
20404
|
+
}
|
|
20405
|
+
const NETWORK_PLUGIN_NAME = "@sailfish-rrweb/rrweb/network@1";
|
|
20406
|
+
const getRecordNetworkPlugin = (options) => ({
|
|
20407
|
+
name: NETWORK_PLUGIN_NAME,
|
|
20408
|
+
observer: initNetworkObserver,
|
|
20409
|
+
options
|
|
20410
|
+
});
|
|
19893
20411
|
/*! *****************************************************************************
|
|
19894
20412
|
Copyright (c) Microsoft Corporation. All rights reserved.
|
|
19895
20413
|
Licensed under the Apache License, Version 2.0 (the "License"); you may not use
|
|
@@ -20457,13 +20975,13 @@
|
|
|
20457
20975
|
return ReconnectingWebSocket2;
|
|
20458
20976
|
}()
|
|
20459
20977
|
);
|
|
20460
|
-
const version = "1.0.0-beta-
|
|
20978
|
+
const version = "1.0.0-beta-2";
|
|
20461
20979
|
function initializeWebSocket(backendApi, apiKey, sessionId) {
|
|
20462
20980
|
const wsHost = getWebSocketHost(backendApi);
|
|
20463
20981
|
const wsScheme = window.location.protocol === "https:" ? "wss" : "ws";
|
|
20464
20982
|
const wsUrl = `${wsScheme}://${wsHost}/ws/notify/?apiKey=${apiKey}&sessionId=${sessionId}&sender=JS%2FTS&version=${version}`;
|
|
20465
20983
|
const options = {
|
|
20466
|
-
connectionTimeout:
|
|
20984
|
+
connectionTimeout: 5e3
|
|
20467
20985
|
};
|
|
20468
20986
|
const webSocket = new ReconnectingWebSocket(wsUrl, [], options);
|
|
20469
20987
|
return webSocket;
|
|
@@ -20475,24 +20993,6 @@
|
|
|
20475
20993
|
}
|
|
20476
20994
|
const MASK_CLASS = "sailfishSanitize";
|
|
20477
20995
|
function maskInputFn(text, node2) {
|
|
20478
|
-
var _a2;
|
|
20479
|
-
if (node2.type === "hidden") {
|
|
20480
|
-
return "";
|
|
20481
|
-
}
|
|
20482
|
-
const patterns = {
|
|
20483
|
-
creditCard: /\b(?:\d[ -]*?){13,16}\b/,
|
|
20484
|
-
ssn: /\b\d{3}-\d{2}-\d{4}\b/
|
|
20485
|
-
};
|
|
20486
|
-
const MASK_CLASS2 = "mask";
|
|
20487
|
-
if (node2.closest(`.${MASK_CLASS2}`)) {
|
|
20488
|
-
return "*".repeat(text.length);
|
|
20489
|
-
} else if (node2.hasAttribute("data-cc") || (((_a2 = node2.getAttribute("autocomplete")) == null ? void 0 : _a2.startsWith("cc-")) ?? false) || patterns.creditCard.test(text)) {
|
|
20490
|
-
return "**** **** **** " + text.slice(-4);
|
|
20491
|
-
} else if (node2.hasAttribute("data-ssn") || patterns.ssn.test(text)) {
|
|
20492
|
-
return "***-**-" + text.slice(-4);
|
|
20493
|
-
} else if (node2.hasAttribute("data-dob")) {
|
|
20494
|
-
return "**/**/" + text.slice(-4);
|
|
20495
|
-
}
|
|
20496
20996
|
return text;
|
|
20497
20997
|
}
|
|
20498
20998
|
async function initializeRecording(captureSettings, consoleRecordSettings, networkRecordSettings, backendApi, apiKey, sessionId) {
|
|
@@ -20502,8 +21002,8 @@
|
|
|
20502
21002
|
cacheEvents(event);
|
|
20503
21003
|
},
|
|
20504
21004
|
plugins: [
|
|
20505
|
-
getRecordConsolePlugin(consoleRecordSettings)
|
|
20506
|
-
|
|
21005
|
+
getRecordConsolePlugin(consoleRecordSettings),
|
|
21006
|
+
getRecordNetworkPlugin(networkRecordSettings)
|
|
20507
21007
|
],
|
|
20508
21008
|
maskInputOptions: { text: true },
|
|
20509
21009
|
// Fix the incorrect property name
|
|
@@ -20569,7 +21069,7 @@
|
|
|
20569
21069
|
backendApi
|
|
20570
21070
|
}) {
|
|
20571
21071
|
var _a2, _b;
|
|
20572
|
-
const sessionId = v4();
|
|
21072
|
+
const sessionId = v4$1();
|
|
20573
21073
|
try {
|
|
20574
21074
|
const captureSettingsResponse = await fetchCaptureSettings(
|
|
20575
21075
|
apiKey,
|