forked from off-topic/apps.apple.com
init commit
This commit is contained in:
145
shared/logger/node_modules/@sentry/utils/esm/baggage.js
generated
vendored
Normal file
145
shared/logger/node_modules/@sentry/utils/esm/baggage.js
generated
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
import { isString } from './is.js';
|
||||
import { logger } from './logger.js';
|
||||
|
||||
const BAGGAGE_HEADER_NAME = 'baggage';
|
||||
|
||||
const SENTRY_BAGGAGE_KEY_PREFIX = 'sentry-';
|
||||
|
||||
const SENTRY_BAGGAGE_KEY_PREFIX_REGEX = /^sentry-/;
|
||||
|
||||
/**
|
||||
* Max length of a serialized baggage string
|
||||
*
|
||||
* https://www.w3.org/TR/baggage/#limits
|
||||
*/
|
||||
const MAX_BAGGAGE_STRING_LENGTH = 8192;
|
||||
|
||||
/**
|
||||
* Takes a baggage header and turns it into Dynamic Sampling Context, by extracting all the "sentry-" prefixed values
|
||||
* from it.
|
||||
*
|
||||
* @param baggageHeader A very bread definition of a baggage header as it might appear in various frameworks.
|
||||
* @returns The Dynamic Sampling Context that was found on `baggageHeader`, if there was any, `undefined` otherwise.
|
||||
*/
|
||||
function baggageHeaderToDynamicSamplingContext(
|
||||
// Very liberal definition of what any incoming header might look like
|
||||
baggageHeader,
|
||||
) {
|
||||
if (!isString(baggageHeader) && !Array.isArray(baggageHeader)) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Intermediary object to store baggage key value pairs of incoming baggage headers on.
|
||||
// It is later used to read Sentry-DSC-values from.
|
||||
let baggageObject = {};
|
||||
|
||||
if (Array.isArray(baggageHeader)) {
|
||||
// Combine all baggage headers into one object containing the baggage values so we can later read the Sentry-DSC-values from it
|
||||
baggageObject = baggageHeader.reduce((acc, curr) => {
|
||||
const currBaggageObject = baggageHeaderToObject(curr);
|
||||
return {
|
||||
...acc,
|
||||
...currBaggageObject,
|
||||
};
|
||||
}, {});
|
||||
} else {
|
||||
// Return undefined if baggage header is an empty string (technically an empty baggage header is not spec conform but
|
||||
// this is how we choose to handle it)
|
||||
if (!baggageHeader) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
baggageObject = baggageHeaderToObject(baggageHeader);
|
||||
}
|
||||
|
||||
// Read all "sentry-" prefixed values out of the baggage object and put it onto a dynamic sampling context object.
|
||||
const dynamicSamplingContext = Object.entries(baggageObject).reduce((acc, [key, value]) => {
|
||||
if (key.match(SENTRY_BAGGAGE_KEY_PREFIX_REGEX)) {
|
||||
const nonPrefixedKey = key.slice(SENTRY_BAGGAGE_KEY_PREFIX.length);
|
||||
acc[nonPrefixedKey] = value;
|
||||
}
|
||||
return acc;
|
||||
}, {});
|
||||
|
||||
// Only return a dynamic sampling context object if there are keys in it.
|
||||
// A keyless object means there were no sentry values on the header, which means that there is no DSC.
|
||||
if (Object.keys(dynamicSamplingContext).length > 0) {
|
||||
return dynamicSamplingContext ;
|
||||
} else {
|
||||
return undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a Dynamic Sampling Object into a baggage header by prefixing all the keys on the object with "sentry-".
|
||||
*
|
||||
* @param dynamicSamplingContext The Dynamic Sampling Context to turn into a header. For convenience and compatibility
|
||||
* with the `getDynamicSamplingContext` method on the Transaction class ,this argument can also be `undefined`. If it is
|
||||
* `undefined` the function will return `undefined`.
|
||||
* @returns a baggage header, created from `dynamicSamplingContext`, or `undefined` either if `dynamicSamplingContext`
|
||||
* was `undefined`, or if `dynamicSamplingContext` didn't contain any values.
|
||||
*/
|
||||
function dynamicSamplingContextToSentryBaggageHeader(
|
||||
// this also takes undefined for convenience and bundle size in other places
|
||||
dynamicSamplingContext,
|
||||
) {
|
||||
// Prefix all DSC keys with "sentry-" and put them into a new object
|
||||
const sentryPrefixedDSC = Object.entries(dynamicSamplingContext).reduce(
|
||||
(acc, [dscKey, dscValue]) => {
|
||||
if (dscValue) {
|
||||
acc[`${SENTRY_BAGGAGE_KEY_PREFIX}${dscKey}`] = dscValue;
|
||||
}
|
||||
return acc;
|
||||
},
|
||||
{},
|
||||
);
|
||||
|
||||
return objectToBaggageHeader(sentryPrefixedDSC);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will parse a baggage header, which is a simple key-value map, into a flat object.
|
||||
*
|
||||
* @param baggageHeader The baggage header to parse.
|
||||
* @returns a flat object containing all the key-value pairs from `baggageHeader`.
|
||||
*/
|
||||
function baggageHeaderToObject(baggageHeader) {
|
||||
return baggageHeader
|
||||
.split(',')
|
||||
.map(baggageEntry => baggageEntry.split('=').map(keyOrValue => decodeURIComponent(keyOrValue.trim())))
|
||||
.reduce((acc, [key, value]) => {
|
||||
acc[key] = value;
|
||||
return acc;
|
||||
}, {});
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns a flat object (key-value pairs) into a baggage header, which is also just key-value pairs.
|
||||
*
|
||||
* @param object The object to turn into a baggage header.
|
||||
* @returns a baggage header string, or `undefined` if the object didn't have any values, since an empty baggage header
|
||||
* is not spec compliant.
|
||||
*/
|
||||
function objectToBaggageHeader(object) {
|
||||
if (Object.keys(object).length === 0) {
|
||||
// An empty baggage header is not spec compliant: We return undefined.
|
||||
return undefined;
|
||||
}
|
||||
|
||||
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) {
|
||||
(typeof __SENTRY_DEBUG__ === 'undefined' || __SENTRY_DEBUG__) &&
|
||||
logger.warn(
|
||||
`Not adding key: ${objectKey} with val: ${objectValue} to baggage header due to exceeding baggage size limits.`,
|
||||
);
|
||||
return baggageHeader;
|
||||
} else {
|
||||
return newBaggageHeader;
|
||||
}
|
||||
}, '');
|
||||
}
|
||||
|
||||
export { BAGGAGE_HEADER_NAME, MAX_BAGGAGE_STRING_LENGTH, SENTRY_BAGGAGE_KEY_PREFIX, SENTRY_BAGGAGE_KEY_PREFIX_REGEX, baggageHeaderToDynamicSamplingContext, dynamicSamplingContextToSentryBaggageHeader };
|
||||
//# sourceMappingURL=baggage.js.map
|
||||
Reference in New Issue
Block a user