mirror of
https://github.com/rxliuli/apps.apple.com.git
synced 2025-11-09 22:00:32 +00:00
816 lines
28 KiB
JavaScript
816 lines
28 KiB
JavaScript
var __defProp = Object.defineProperty;
|
|
var __defProps = Object.defineProperties;
|
|
var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
|
|
var __getOwnPropSymbols = Object.getOwnPropertySymbols;
|
|
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
var __propIsEnum = Object.prototype.propertyIsEnumerable;
|
|
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
|
|
var __spreadValues = (a, b) => {
|
|
for (var prop in b || (b = {}))
|
|
if (__hasOwnProp.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
if (__getOwnPropSymbols)
|
|
for (var prop of __getOwnPropSymbols(b)) {
|
|
if (__propIsEnum.call(b, prop))
|
|
__defNormalProp(a, prop, b[prop]);
|
|
}
|
|
return a;
|
|
};
|
|
var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
|
|
|
|
// src/config.ts
|
|
import { SDK_VERSION as SDK_VERSION2 } from "@sentry/browser";
|
|
|
|
// src/transports/fetch.ts
|
|
import { rejectedSyncPromise } from "@sentry/utils";
|
|
|
|
// src/transports/base.ts
|
|
import {
|
|
createEnvelope,
|
|
envelopeItemTypeToDataCategory,
|
|
forEachEnvelopeItem,
|
|
isRateLimited,
|
|
logger,
|
|
makePromiseBuffer,
|
|
resolvedSyncPromise,
|
|
SentryError,
|
|
serializeEnvelope,
|
|
updateRateLimits
|
|
} from "@sentry/utils";
|
|
var DEFAULT_TRANSPORT_BUFFER_SIZE = 30;
|
|
function createTransport(options, makeRequest, buffer = makePromiseBuffer(
|
|
options.bufferSize || DEFAULT_TRANSPORT_BUFFER_SIZE
|
|
)) {
|
|
let rateLimits = {};
|
|
const flush = (timeout) => buffer.drain(timeout);
|
|
function send(envelope) {
|
|
const filteredEnvelopeItems = [];
|
|
forEachEnvelopeItem(envelope, (item, type) => {
|
|
const envelopeItemDataCategory = envelopeItemTypeToDataCategory(type);
|
|
if (isRateLimited(rateLimits, envelopeItemDataCategory)) {
|
|
const event = getEventForEnvelopeItem(item, type);
|
|
options.recordDroppedEvent("ratelimit_backoff", envelopeItemDataCategory, event);
|
|
} else {
|
|
filteredEnvelopeItems.push(item);
|
|
}
|
|
});
|
|
if (filteredEnvelopeItems.length === 0) {
|
|
return resolvedSyncPromise();
|
|
}
|
|
const filteredEnvelope = createEnvelope(envelope[0], filteredEnvelopeItems);
|
|
const recordEnvelopeLoss = (reason) => {
|
|
forEachEnvelopeItem(filteredEnvelope, (item, type) => {
|
|
const event = getEventForEnvelopeItem(item, type);
|
|
options.recordDroppedEvent(reason, envelopeItemTypeToDataCategory(type), event);
|
|
});
|
|
};
|
|
const getRequest = options.getRequest || ((envelope2) => ({
|
|
body: serializeEnvelope(envelope2, options.textEncoder)
|
|
}));
|
|
const request = getRequest(filteredEnvelope);
|
|
if (!request) {
|
|
return resolvedSyncPromise();
|
|
}
|
|
const requestTask = () => makeRequest(request).then(
|
|
(response) => {
|
|
if (response.statusCode !== void 0 && (response.statusCode < 200 || response.statusCode >= 300)) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && logger.warn(`Sentry responded with status code ${response.statusCode} to sent event.`);
|
|
}
|
|
rateLimits = updateRateLimits(rateLimits, response);
|
|
return response;
|
|
},
|
|
(error) => {
|
|
recordEnvelopeLoss("network_error");
|
|
throw error;
|
|
}
|
|
);
|
|
return buffer.add(requestTask).then(
|
|
(result) => result,
|
|
(error) => {
|
|
if (error instanceof SentryError) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && logger.error("Skipped sending event because buffer is full.");
|
|
recordEnvelopeLoss("queue_overflow");
|
|
return resolvedSyncPromise();
|
|
} else {
|
|
throw error;
|
|
}
|
|
}
|
|
);
|
|
}
|
|
send.__sentry__baseTransport__ = true;
|
|
return {
|
|
send,
|
|
flush
|
|
};
|
|
}
|
|
function getEventForEnvelopeItem(item, type) {
|
|
if (type !== "event" && type !== "transaction") {
|
|
return void 0;
|
|
}
|
|
return Array.isArray(item) ? item[1] : void 0;
|
|
}
|
|
|
|
// src/transports/utils.ts
|
|
import { isNativeFetch, logger as logger2 } from "@sentry/utils";
|
|
import { GLOBAL_OBJ } from "@sentry/utils";
|
|
var WINDOW = GLOBAL_OBJ;
|
|
var cachedFetchImpl = void 0;
|
|
function getNativeFetchImplementation() {
|
|
if (cachedFetchImpl) {
|
|
return cachedFetchImpl;
|
|
}
|
|
if (isNativeFetch(WINDOW.fetch)) {
|
|
return cachedFetchImpl = WINDOW.fetch.bind(WINDOW);
|
|
}
|
|
const document = WINDOW.document;
|
|
let fetchImpl = WINDOW.fetch;
|
|
if (document && typeof document.createElement === "function") {
|
|
try {
|
|
const sandbox = document.createElement("iframe");
|
|
sandbox.hidden = true;
|
|
document.head.appendChild(sandbox);
|
|
const contentWindow = sandbox.contentWindow;
|
|
if (contentWindow && contentWindow.fetch) {
|
|
fetchImpl = contentWindow.fetch;
|
|
}
|
|
document.head.removeChild(sandbox);
|
|
} catch (e) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && logger2.warn("Could not create sandbox iframe for pure fetch check, bailing to window.fetch: ", e);
|
|
}
|
|
}
|
|
return cachedFetchImpl = fetchImpl.bind(WINDOW);
|
|
}
|
|
function clearCachedFetchImplementation() {
|
|
cachedFetchImpl = void 0;
|
|
}
|
|
|
|
// src/transports/fetch.ts
|
|
function makeFetchTransport(options, nativeFetch = getNativeFetchImplementation()) {
|
|
let pendingBodySize = 0;
|
|
let pendingCount = 0;
|
|
function makeRequest(request) {
|
|
const requestSize = request.body.length;
|
|
pendingBodySize += requestSize;
|
|
pendingCount++;
|
|
const requestOptions = __spreadValues({
|
|
body: request.body,
|
|
method: "POST",
|
|
referrerPolicy: "origin",
|
|
headers: request.headers,
|
|
keepalive: pendingBodySize <= 6e4 && pendingCount < 15
|
|
}, options.fetchOptions);
|
|
try {
|
|
return nativeFetch(request.url, requestOptions).then((response) => {
|
|
pendingBodySize -= requestSize;
|
|
pendingCount--;
|
|
return {
|
|
statusCode: response.status,
|
|
headers: {
|
|
"x-sentry-rate-limits": response.headers.get("X-Sentry-Rate-Limits"),
|
|
"retry-after": response.headers.get("Retry-After")
|
|
}
|
|
};
|
|
});
|
|
} catch (e) {
|
|
clearCachedFetchImplementation();
|
|
pendingBodySize -= requestSize;
|
|
pendingCount--;
|
|
return rejectedSyncPromise(e);
|
|
}
|
|
}
|
|
return createTransport(options, makeRequest);
|
|
}
|
|
|
|
// src/transports/xhr.ts
|
|
import { SyncPromise } from "@sentry/utils";
|
|
var XHR_READYSTATE_DONE = 4;
|
|
function makeXHRTransport(options) {
|
|
function makeRequest(request) {
|
|
return new SyncPromise((resolve, reject) => {
|
|
const xhr = new XMLHttpRequest();
|
|
xhr.onerror = reject;
|
|
xhr.onreadystatechange = () => {
|
|
if (xhr.readyState === XHR_READYSTATE_DONE) {
|
|
resolve({
|
|
statusCode: xhr.status,
|
|
headers: {
|
|
"x-sentry-rate-limits": xhr.getResponseHeader("X-Sentry-Rate-Limits"),
|
|
"retry-after": xhr.getResponseHeader("Retry-After")
|
|
}
|
|
});
|
|
}
|
|
};
|
|
xhr.open("POST", request.url);
|
|
for (const header in request.headers) {
|
|
if (Object.prototype.hasOwnProperty.call(request.headers, header)) {
|
|
xhr.setRequestHeader(header, request.headers[header]);
|
|
}
|
|
}
|
|
xhr.send(request.body);
|
|
});
|
|
}
|
|
return createTransport(options, makeRequest);
|
|
}
|
|
|
|
// src/transport.ts
|
|
import { supportsFetch } from "@sentry/utils";
|
|
|
|
// src/ingestion-event.ts
|
|
function envelopeToIngestionEvents(envelope, options) {
|
|
const [_envelopeHeader, items] = envelope;
|
|
delete _envelopeHeader.dsn;
|
|
const sharedFields = {
|
|
_envelopeHeader,
|
|
project: options.project,
|
|
v: 4
|
|
};
|
|
return items.map((item) => {
|
|
const itemType = item[0].type;
|
|
if (itemType !== "event" && itemType !== "transaction") {
|
|
return __spreadProps(__spreadValues({}, sharedFields), {
|
|
_itemHeader: item[0],
|
|
_debugLogs: [
|
|
`Items of type "${itemType}" are not supported yet. Dropped the item.`
|
|
]
|
|
});
|
|
}
|
|
const [_itemHeader, payload] = item;
|
|
return __spreadValues(__spreadProps(__spreadValues({}, sharedFields), {
|
|
_itemHeader
|
|
}), payload);
|
|
});
|
|
}
|
|
|
|
// src/utils.ts
|
|
import { getCurrentHub, SDK_VERSION } from "@sentry/browser";
|
|
function isHeadlessBrowser() {
|
|
return navigator.userAgent === void 0 || navigator.appVersion === void 0 || navigator.plugins === void 0 || navigator.languages === void 0 || navigator.languages.length === 0 || navigator.language === "" || navigator.webdriver || navigator.plugins.length === 0 || /HeadlessChrome/.test(navigator.userAgent) || /headless/i.test(navigator.appVersion);
|
|
}
|
|
function versionMismatchErrorMessage(sdkVersion) {
|
|
sdkVersion || (sdkVersion = "unknown");
|
|
return `Version mismatch between the installed Sentry SDK version (${sdkVersion}) and supported SDK version (${SUPPORTED_SENTRY_VERSION}) by SentryKit. Make sure to use supported version of the Sentry SDK (${SUPPORTED_SENTRY_VERSION}).`;
|
|
}
|
|
function checkSentryKitIsCompatibleWith(sdkVersion) {
|
|
if (sdkVersion !== SUPPORTED_SENTRY_VERSION) {
|
|
console.error(
|
|
`[SentryKit Versioning Error] ${versionMismatchErrorMessage(
|
|
sdkVersion
|
|
)} All sent data will be discarded.`
|
|
);
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
function checkSentrySDKCompatibility() {
|
|
return checkSentryKitIsCompatibleWith(SDK_VERSION);
|
|
}
|
|
function checkEnvelopeSentrySDKCompatibility(envelope) {
|
|
var _a;
|
|
const sdkVersion = (_a = envelope[0].sdk) == null ? void 0 : _a.version;
|
|
return checkSentryKitIsCompatibleWith(sdkVersion);
|
|
}
|
|
var correctSetupGuide = `The correct way to use SentryKit is as follows:
|
|
|
|
import {createSentryConfig} from '@amp-metrics/sentrykit'
|
|
|
|
Sentry.init(createSentryConfig({
|
|
// all your configs
|
|
}))`;
|
|
function monitorSentryConfig(config) {
|
|
;
|
|
config.__sentrykit_original_config = __spreadValues({}, config);
|
|
return config;
|
|
}
|
|
function monitorSentryHubBindClient() {
|
|
const hub = getCurrentHub();
|
|
const originalBindClient = hub.bindClient;
|
|
hub.bindClient = (client) => {
|
|
assertCorrectSentryKitConfiguration(client.getOptions());
|
|
originalBindClient.call(hub, client);
|
|
};
|
|
}
|
|
function assertCorrectSentryKitConfiguration(config) {
|
|
var _a, _b;
|
|
const sdkVersion = (_b = (_a = config._metadata) == null ? void 0 : _a.sdk) == null ? void 0 : _b.version;
|
|
if (sdkVersion !== SUPPORTED_SENTRY_VERSION) {
|
|
throw new Error(
|
|
`[SentryKit Initialization Error] ${versionMismatchErrorMessage(
|
|
sdkVersion
|
|
)}`
|
|
);
|
|
}
|
|
const originalConfig = config.__sentrykit_original_config;
|
|
if (!originalConfig) {
|
|
throw new Error(
|
|
`[SentryKit Initialization Error] Configuration has to be generated through \`createSentryConfig\` function. ${correctSetupGuide}`
|
|
);
|
|
}
|
|
for (const key in originalConfig) {
|
|
if (key === "integrations") {
|
|
continue;
|
|
}
|
|
if (originalConfig[key] !== config[key]) {
|
|
throw new Error(
|
|
`[SentryKit Initialization Error] Configuration generated through \`createSentryConfig\` function has been changed. ${correctSetupGuide}`
|
|
);
|
|
}
|
|
}
|
|
}
|
|
|
|
// src/logger.ts
|
|
var originalLog = console.log;
|
|
var enabled = false;
|
|
var enableLogger = () => {
|
|
enabled = true;
|
|
};
|
|
var createLogger = (prefix) => (...args) => {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && enabled && originalLog(prefix, ...args);
|
|
};
|
|
|
|
// src/privacy/rules.ts
|
|
var debug = /* @__PURE__ */ createLogger("[SentryKit Privacy rules]");
|
|
function visit(obj, callback, parentContext) {
|
|
const parentPath = (parentContext == null ? void 0 : parentContext.path) ? parentContext.path + "." : "";
|
|
const _visit = (key) => {
|
|
const path = parentPath + key;
|
|
const value = obj[key];
|
|
const action = callback({
|
|
obj,
|
|
key,
|
|
value,
|
|
path,
|
|
parentContext
|
|
});
|
|
if (action === "remove") {
|
|
return action;
|
|
}
|
|
if (value !== null && typeof value === "object") {
|
|
visit(value, callback, {
|
|
obj,
|
|
key,
|
|
value,
|
|
path,
|
|
parentContext
|
|
});
|
|
}
|
|
};
|
|
if (Array.isArray(obj)) {
|
|
for (let i = 0; i < obj.length; i++) {
|
|
const action = _visit(i.toString());
|
|
if (action === "remove") {
|
|
obj.splice(i, 1);
|
|
i--;
|
|
}
|
|
}
|
|
} else {
|
|
for (const key in obj) {
|
|
const action = _visit(key);
|
|
if (action === "remove") {
|
|
delete obj[key];
|
|
}
|
|
}
|
|
}
|
|
}
|
|
var matchesPath = (rule, eventType, context) => {
|
|
if ((rule.type === "url" || rule.type === "url-query") && typeof context.obj[context.key] !== "string") {
|
|
return false;
|
|
}
|
|
if (rule.type === "timestamp" && typeof context.obj[context.key] !== "number") {
|
|
return false;
|
|
}
|
|
if (!rule.matchPath) {
|
|
if (rule.type === "url" || rule.type === "url-query") {
|
|
return isURLField(context);
|
|
}
|
|
if (rule.type === "timestamp") {
|
|
return isTimestampField(context);
|
|
}
|
|
return true;
|
|
}
|
|
return typeof rule.matchPath === "function" ? rule.matchPath({
|
|
eventType,
|
|
path: context.path,
|
|
key: context.key,
|
|
value: context.value
|
|
}) : rule.matchPath.test(context.path);
|
|
};
|
|
var matchesQuery = (rule, eventType, context, queryName, queryValue) => {
|
|
if (rule.type !== "url-query") {
|
|
return false;
|
|
}
|
|
if (!rule.matchQueryName) {
|
|
return true;
|
|
}
|
|
return typeof rule.matchQueryName === "function" ? rule.matchQueryName({
|
|
eventType,
|
|
path: context.path,
|
|
key: context.key,
|
|
url: context.value,
|
|
queryName,
|
|
queryValue
|
|
}) : rule.matchQueryName.test(queryName);
|
|
};
|
|
var KnownURLFields = [
|
|
(context) => /^spans\.\d+\.data\.url$/.test(context.path) && context.parentContext.obj.op === "http.client" && (Object.defineProperty(context.obj, "_url", {
|
|
enumerable: false,
|
|
value: context.value
|
|
}) || true),
|
|
(context) => /^spans\.\d+\.description$/.test(context.path) && context.obj.op === "http.client" && context.obj.data && context.obj.description === `${context.obj.data.method} ${context.obj.data._url || context.obj.data.url}`,
|
|
(context) => /^breadcrumbs\.\d+\.data\.url$/.test(context.path) && (context.parentContext.obj.category === "fetch" || context.parentContext.obj.category === "xhr"),
|
|
(context) => /^breadcrumbs\.\d+\.data\.from$/.test(context.path) && context.parentContext.obj.category === "navigation",
|
|
(context) => /^breadcrumbs\.\d+\.data\.to$/.test(context.path) && context.parentContext.obj.category === "navigation",
|
|
(context) => /^request\.url$/.test(context.path),
|
|
(context) => /^request\.headers\.Referer$/.test(context.path)
|
|
];
|
|
var isURLField = (context) => KnownURLFields.some((test) => test(context));
|
|
var isTimestampField = (context) => {
|
|
return typeof context.value === "number" && context.path.toLowerCase().endsWith("timestamp");
|
|
};
|
|
var processForPrivacy = (event, rules) => {
|
|
const eventType = event._itemHeader.type === "transaction" ? "transaction" : "error";
|
|
visit(event, (context) => {
|
|
const { path, key, obj } = context;
|
|
for (const [i, rule] of rules.entries()) {
|
|
if (!matchesPath(rule, eventType, context)) {
|
|
continue;
|
|
}
|
|
if ("action" in rule && rule.action === "keep") {
|
|
continue;
|
|
}
|
|
if (rule.type === "timestamp") {
|
|
const timestamp = obj[key];
|
|
const timestampOrPrecision = typeof rule.precision === "function" ? rule.precision({
|
|
eventType,
|
|
path,
|
|
key,
|
|
timestamp
|
|
}) : rule.precision;
|
|
if (typeof timestampOrPrecision === "number") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && timestamp !== timestampOrPrecision && debug(
|
|
`Setting timestamp to a new value of "${timestampOrPrecision}" for path: "${path}"`
|
|
);
|
|
obj[key] = timestampOrPrecision;
|
|
} else if (timestampOrPrecision === "seconds") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Reducing timestamp to "${timestampOrPrecision}" for path: "${path}"`
|
|
);
|
|
obj[key] = Math.round(timestamp);
|
|
} else if (timestampOrPrecision === "minutes") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Reducing timestamp to "${timestampOrPrecision}" for path: "${path}"`
|
|
);
|
|
obj[key] = Math.round(timestamp / 60) * 60;
|
|
}
|
|
} else if (rule.type === "url-query") {
|
|
const url = obj[key];
|
|
const [base, oldQuery = ""] = url.split("?");
|
|
const queryParams = new URLSearchParams(oldQuery);
|
|
const entries = [...queryParams.entries()];
|
|
entries.forEach(([queryName, queryValue]) => {
|
|
if (matchesQuery(rule, eventType, context, queryName, queryValue)) {
|
|
const hasActionAfterwards = rules.slice(i + 1).some(
|
|
(r) => matchesPath(r, eventType, context) && matchesQuery(r, eventType, context, queryName, queryValue)
|
|
);
|
|
if (hasActionAfterwards) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Skipping the active rule as there is an overriding rule for the query "${queryName}" in the url "${url}" in path "${path}".`
|
|
);
|
|
return;
|
|
}
|
|
if (rule.action === "remove") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Removing query "${queryName}" from the url "${url}" in the path: "${path}" (value was: "${queryValue}")`
|
|
);
|
|
queryParams.delete(queryName);
|
|
} else if (rule.action === "replace") {
|
|
const newValue = typeof rule.replace === "function" ? rule.replace({
|
|
key,
|
|
path,
|
|
url,
|
|
queryName,
|
|
queryValue,
|
|
eventType
|
|
}) : rule.replace;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && newValue !== queryValue && debug(
|
|
`Setting query "${queryName}" in the url "${url}" to a new value of "${newValue}" for path: "${path}" (value was: "${queryValue}")`
|
|
);
|
|
queryParams.set(queryName, newValue);
|
|
}
|
|
}
|
|
});
|
|
const query = queryParams.toString();
|
|
obj[key] = base + (query ? `?${query}` : "");
|
|
} else if (rule.type === "url") {
|
|
const hasActionAfterwards = rules.slice(i + 1).some((r) => matchesPath(r, eventType, context) && r.type === "url");
|
|
if (hasActionAfterwards) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Skipping the active rule as there is an overriding rule for the url "${obj[key]}" in path "${path}".`
|
|
);
|
|
continue;
|
|
}
|
|
if (rule.action === "remove") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(`Removing the url "${obj[key]}" in the path: "${path}"`);
|
|
return "remove";
|
|
} else if (rule.action === "replace") {
|
|
const newValue = typeof rule.replace === "function" ? rule.replace({
|
|
key,
|
|
path,
|
|
url: obj[key],
|
|
eventType
|
|
}) : rule.replace;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && newValue !== obj[key] && debug(
|
|
`Setting the url"${obj[key]}" to a new value of "${newValue}" for path: "${path}" (value was: "${obj[key]}")`
|
|
);
|
|
obj[key] = newValue;
|
|
}
|
|
} else if (rule.type === "any" && "action" in rule) {
|
|
const hasActionAfterwards = rules.slice(i + 1).some((r) => matchesPath(r, eventType, context) && r.type === "any");
|
|
if (hasActionAfterwards) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(
|
|
`Skipping the active rule as there is an overriding rule for the path "${path}".`
|
|
);
|
|
continue;
|
|
}
|
|
if (rule.action === "remove") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug(`Removing the path "${path}" (value was: "${obj[key]}")`);
|
|
return "remove";
|
|
} else if (rule.action === "replace") {
|
|
const newValue = typeof rule.replace === "function" ? rule.replace({
|
|
key,
|
|
path,
|
|
value: obj[key],
|
|
eventType
|
|
}) : rule.replace;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && newValue !== obj[key] && debug(
|
|
`Setting a new value of "${newValue}" for path: "${path}" (value was: "${obj[key]}")`
|
|
);
|
|
obj[key] = newValue;
|
|
}
|
|
}
|
|
}
|
|
});
|
|
return event;
|
|
};
|
|
|
|
// src/transport.ts
|
|
function createTransportUrl(ingestUrl, topic) {
|
|
const url = new URL(ingestUrl);
|
|
url.pathname = "/report/2/" + topic;
|
|
return url.toString();
|
|
}
|
|
function makeTransport(options) {
|
|
options.getRequest = (envelope) => {
|
|
if (!checkEnvelopeSentrySDKCompatibility(envelope)) {
|
|
return false;
|
|
}
|
|
const events = envelopeToIngestionEvents(
|
|
envelope,
|
|
options.sentryKitConfig
|
|
).map(
|
|
(event) => processForPrivacy(
|
|
JSON.parse(JSON.stringify(event)),
|
|
options.sentryKitConfig.privacyRules
|
|
)
|
|
);
|
|
const topic = events[0]._itemHeader.type === "transaction" ? "traces" : "error";
|
|
const url = createTransportUrl(
|
|
options.sentryKitConfig.ingestUrl,
|
|
options.sentryKitConfig.topic[topic]
|
|
);
|
|
return {
|
|
url,
|
|
body: JSON.stringify({ events }),
|
|
headers: {
|
|
"Content-type": "application/json"
|
|
}
|
|
};
|
|
};
|
|
return supportsFetch() ? makeFetchTransport(options) : makeXHRTransport(options);
|
|
}
|
|
|
|
// src/privacy/settings.ts
|
|
var debug2 = /* @__PURE__ */ createLogger("[SentryKit Privacy settings]");
|
|
function createPrivacyRulesFrom({
|
|
allowQueryParams,
|
|
allowExtra,
|
|
allowTags,
|
|
timestampPrecision
|
|
}) {
|
|
const privacyRules = [];
|
|
if (allowTags) {
|
|
privacyRules.push({
|
|
type: "any",
|
|
matchPath: ({ path, key }) => {
|
|
const shouldKeep = path === `tags.${key}` && allowTags.includes(key);
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && shouldKeep && debug2(`Keeping the tag "${key}" for path: "${path}"`);
|
|
return shouldKeep;
|
|
},
|
|
action: "keep"
|
|
});
|
|
}
|
|
if (allowExtra) {
|
|
privacyRules.push({
|
|
type: "any",
|
|
matchPath: ({ path, key }) => {
|
|
const shouldKeep = path === `extra.${key}` && allowExtra.includes(key);
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && shouldKeep && debug2(`Keeping the extra "${key}" for path: "${path}"`);
|
|
return shouldKeep;
|
|
},
|
|
action: "keep"
|
|
});
|
|
}
|
|
if (allowQueryParams) {
|
|
privacyRules.push({
|
|
type: "url-query",
|
|
matchQueryName: ({ url, queryName, path }) => {
|
|
const params = typeof allowQueryParams === "function" ? allowQueryParams(url) : allowQueryParams;
|
|
const shouldKeep = params.includes(queryName);
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && shouldKeep && debug2(`Keeping the query name "${queryName}" for path: "${path}"`);
|
|
return shouldKeep;
|
|
},
|
|
action: "keep"
|
|
});
|
|
}
|
|
if (timestampPrecision) {
|
|
privacyRules.push({
|
|
type: "timestamp",
|
|
precision: ({ eventType, timestamp, path }) => {
|
|
if (eventType === "error") {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug2(
|
|
`Reducing timestamp to "${timestampPrecision}" for path: "${path}"`
|
|
);
|
|
return timestampPrecision;
|
|
}
|
|
return timestamp;
|
|
}
|
|
});
|
|
}
|
|
return privacyRules;
|
|
}
|
|
|
|
// src/config.ts
|
|
var debug3 = /* @__PURE__ */ createLogger("[SentryKit Config]");
|
|
var SUPPORTED_SENTRY_VERSION = "7.57.0";
|
|
var ENVIRONMENTS = {
|
|
prod: "prod",
|
|
qa: "qa"
|
|
};
|
|
var INGEST_URLS = {
|
|
prod: "https://xp.apple.com",
|
|
qa: "https://xp-qa.apple.com"
|
|
};
|
|
var defaultPrivacyRules = [
|
|
{
|
|
type: "any",
|
|
matchPath: /tags\..+$/,
|
|
action: "remove"
|
|
},
|
|
{
|
|
type: "any",
|
|
matchPath: /tags\.(http\.status_code|visibilitychange|effectiveConnectionType|connectionType|deviceMemory|hardwareConcurrency|lcp\..+)$/,
|
|
action: "keep"
|
|
},
|
|
{
|
|
type: "any",
|
|
matchPath: /^extra\.[^.]+$/,
|
|
action: "remove"
|
|
},
|
|
{
|
|
type: "any",
|
|
matchPath: /^extra\.arguments$/,
|
|
action: "keep"
|
|
},
|
|
{
|
|
type: "any",
|
|
matchPath: /^user\.[^.]+$/,
|
|
action: "remove"
|
|
},
|
|
{
|
|
type: "url-query",
|
|
action: "replace",
|
|
replace: "REMOVED"
|
|
}
|
|
];
|
|
function baseConfig(userOptions) {
|
|
const privacyRules = typeof userOptions.privacyRules === "function" ? userOptions.privacyRules(defaultPrivacyRules) : userOptions.privacyRules === false ? [] : [...defaultPrivacyRules, ...userOptions.privacyRules || []];
|
|
if (userOptions.privacySettings) {
|
|
privacyRules.push(...createPrivacyRulesFrom(userOptions.privacySettings));
|
|
}
|
|
const config = __spreadProps(__spreadValues({
|
|
transport: makeTransport,
|
|
ingestUrl: "",
|
|
topic: "xp_amp_web_error_log",
|
|
environment: "qa",
|
|
filterHeadless: true,
|
|
maxBreadcrumbs: 0,
|
|
release: void 0,
|
|
redactKeys: void 0,
|
|
sampleRate: void 0,
|
|
tracesSampleRate: void 0,
|
|
tracesSampler: void 0
|
|
}, userOptions), {
|
|
privacyRules,
|
|
dsn: "https://dsn@bypass/1",
|
|
autoSessionTracking: false,
|
|
sendClientReports: false,
|
|
replaysSessionSampleRate: void 0,
|
|
replaysOnErrorSampleRate: void 0
|
|
});
|
|
if (typeof config.topic === "string") {
|
|
config.topic = {
|
|
error: config.topic,
|
|
traces: ""
|
|
};
|
|
}
|
|
const $config = config;
|
|
$config.transportOptions = __spreadProps(__spreadValues({}, $config.transportOptions), {
|
|
sentryKitConfig: $config
|
|
});
|
|
if (!$config.ingestUrl) {
|
|
$config.ingestUrl = $config.environment === ENVIRONMENTS.prod ? INGEST_URLS.prod : INGEST_URLS.qa;
|
|
}
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug3(
|
|
`Initialized with environment "${$config.environment}" and ingestUrl "${$config.ingestUrl}".`
|
|
);
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && debug3(
|
|
$config.topic.traces ? `Tracing topic is set to "${$config.topic.traces}".` : `No tracing topic is set.`
|
|
);
|
|
return $config;
|
|
}
|
|
function beforeHooksOptions(config) {
|
|
const IS_SUPPORTED_SDK = SDK_VERSION2 === SUPPORTED_SENTRY_VERSION;
|
|
const shouldSkipEvent = !IS_SUPPORTED_SDK || config.environment === ENVIRONMENTS.prod && config.filterHeadless && isHeadlessBrowser();
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && shouldSkipEvent && debug3("Events and transactions will not be sent to sentry.");
|
|
return {
|
|
beforeSend: (event, hint) => {
|
|
if (shouldSkipEvent) {
|
|
return null;
|
|
}
|
|
return config.beforeSend ? config.beforeSend(event, hint) : event;
|
|
},
|
|
beforeSendTransaction(event, hint) {
|
|
if (shouldSkipEvent) {
|
|
return null;
|
|
}
|
|
return config.beforeSendTransaction ? config.beforeSendTransaction(event, hint) : event;
|
|
},
|
|
beforeBreadcrumb(breadcrumb, hint) {
|
|
if (breadcrumb.category === "console") {
|
|
return null;
|
|
}
|
|
return config.beforeBreadcrumb ? config.beforeBreadcrumb(breadcrumb, hint) : breadcrumb;
|
|
}
|
|
};
|
|
}
|
|
|
|
// src/index.ts
|
|
checkSentrySDKCompatibility();
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && monitorSentryHubBindClient();
|
|
function createSentryConfig(userOptions) {
|
|
;
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && (userOptions == null ? void 0 : userOptions.debug) && enableLogger();
|
|
const config = baseConfig(userOptions || {});
|
|
if (!config.project) {
|
|
throw new Error(
|
|
"[SentryKit Configuration Error]: The required `project` field is not set."
|
|
);
|
|
}
|
|
const hasTracesConfig = config.tracesSampleRate || config.tracesSampler;
|
|
const hasTracesTopic = config.topic.traces;
|
|
if (hasTracesConfig && !hasTracesTopic) {
|
|
throw new Error(
|
|
"[SentryKit Configuration Error]: The `topic.traces` field is not set while trace sampling is configured."
|
|
);
|
|
}
|
|
if (hasTracesTopic && !hasTracesConfig) {
|
|
throw new Error(
|
|
"[SentryKit Configuration Error]: Trace sampling is configured but `topic.traces` is not set."
|
|
);
|
|
}
|
|
const originalConfig = __spreadValues(__spreadValues({}, config), beforeHooksOptions(config));
|
|
(typeof __SENTRY_DEBUG__ === "undefined" || __SENTRY_DEBUG__) && monitorSentryConfig(originalConfig);
|
|
return originalConfig;
|
|
}
|
|
var SentryKit = { createSentryConfig };
|
|
var src_default = SentryKit;
|
|
export {
|
|
SentryKit,
|
|
createSentryConfig,
|
|
src_default as default
|
|
};
|