summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm/baggage.js
diff options
context:
space:
mode:
authorrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
committerrxliuli <rxliuli@gmail.com>2025-11-04 05:03:50 +0800
commitbce557cc2dc767628bed6aac87301a1be7c5431b (patch)
treeb51a051228d01fe3306cd7626d4a96768aadb944 /shared/logger/node_modules/@sentry/utils/esm/baggage.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm/baggage.js')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/baggage.js145
1 files changed, 145 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/baggage.js b/shared/logger/node_modules/@sentry/utils/esm/baggage.js
new file mode 100644
index 0000000..88297b4
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/baggage.js
@@ -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