@sentry/core
Version:
Base implementation for all Sentry JavaScript SDKs
134 lines (131 loc) • 4.42 kB
JavaScript
import { DEBUG_BUILD } from '../debug-build.js';
import { debug } from './debug-logger.js';
import { isString } from './is.js';
const SENTRY_BAGGAGE_KEY_PREFIX = "sentry-";
const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;
const MAX_BAGGAGE_STRING_LENGTH = 8192;
function baggageHeaderToDynamicSamplingContext(baggageHeader) {
const baggageObject = parseBaggageHeader(baggageHeader);
if (!baggageObject) {
return void 0;
}
const dynamicSamplingContext = Object.entries(baggageObject).reduce((acc, [key, value]) => {
if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {
const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);
acc[nonPrefixedKey] = value;
}
return acc;
}, {});
if (Object.keys(dynamicSamplingContext).length > 0) {
return dynamicSamplingContext;
} else {
return void 0;
}
}
function dynamicSamplingContextToSentryBaggageHeader(dynamicSamplingContext) {
if (!dynamicSamplingContext) {
return void 0;
}
const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce(
(acc, [dscKey, dscValue]) => {
if (dscValue) {
acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;
}
return acc;
},
{}
);
return objectToBaggageHeader(sentryPrefixedDSC);
}
function parseBaggageHeader(baggageHeader) {
if (!baggageHeader || !isString(baggageHeader) && !Array.isArray(baggageHeader)) {
return void 0;
}
if (Array.isArray(baggageHeader)) {
return baggageHeader.reduce((acc, curr) => {
const currBaggageObject = baggageHeaderToObject(curr);
Object.entries(currBaggageObject).forEach(([key, value]) => {
acc[key] = value;
});
return acc;
}, {});
}
return baggageHeaderToObject(baggageHeader);
}
function baggageHeaderToObject(baggageHeader) {
return baggageHeader.split(",").map((baggageEntry) => {
const eqIdx = baggageEntry.indexOf("=");
if (eqIdx === -1) {
return [];
}
const key = baggageEntry.slice(0, eqIdx);
const value = baggageEntry.slice(eqIdx + 1);
return [key, value].map((keyOrValue) => {
try {
return decodeURIComponent(keyOrValue.trim());
} catch {
return;
}
});
}).reduce((acc, [key, value]) => {
if (key && value) {
acc[key] = value;
}
return acc;
}, {});
}
function objectToBaggageHeader(object) {
if (Object.keys(object).length === 0) {
return void 0;
}
return Object.entries(object).reduce((baggageHeader, [objectKey, objectValue], currentIndex) => {
const baggageEntry = `${encodeURIComponent(objectKey)}=${encodeURIComponent(objectValue)}`;
const newBaggageHeader = currentIndex === 0 ? baggageEntry : `${baggageHeader},${baggageEntry}`;
if (newBaggageHeader.length > MAX_BAGGAGE_STRING_LENGTH) {
DEBUG_BUILD && debug.warn(
`Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`
);
return baggageHeader;
} else {
return newBaggageHeader;
}
}, "");
}
function mergeBaggageHeaders(existing, incoming) {
if (!existing) {
return incoming;
}
const existingEntries = parseBaggageHeader(existing);
const incomingEntries = parseBaggageHeader(incoming);
if (!incomingEntries) {
return existing;
}
const merged = {};
let hasNewSentryEntries = false;
const newSentryEntries = {};
const newNonSentryEntries = {};
for (const [key, value] of Object.entries(incomingEntries)) {
if (key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {
newSentryEntries[key] = value;
hasNewSentryEntries = true;
} else {
newNonSentryEntries[key] = value;
}
}
if (existingEntries) {
for (const [key, value] of Object.entries(existingEntries)) {
if (!hasNewSentryEntries || !key.startsWith(SENTRY_BAGGAGE_KEY_PREFIX)) {
merged[key] = value;
}
}
}
if (hasNewSentryEntries) {
Object.assign(merged, newSentryEntries);
}
for (const [key, value] of Object.entries(newNonSentryEntries)) {
merged[key] ?? (merged[key] = value);
}
return objectToBaggageHeader(merged);
}
export { MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader, mergeBaggageHeaders, objectToBaggageHeader, parseBaggageHeader };
//# sourceMappingURL=baggage.js.map