summaryrefslogtreecommitdiff
path: root/shared/logger/node_modules/@sentry/utils/esm/envelope.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/envelope.js
init commit
Diffstat (limited to 'shared/logger/node_modules/@sentry/utils/esm/envelope.js')
-rw-r--r--shared/logger/node_modules/@sentry/utils/esm/envelope.js232
1 files changed, 232 insertions, 0 deletions
diff --git a/shared/logger/node_modules/@sentry/utils/esm/envelope.js b/shared/logger/node_modules/@sentry/utils/esm/envelope.js
new file mode 100644
index 0000000..a2cc042
--- /dev/null
+++ b/shared/logger/node_modules/@sentry/utils/esm/envelope.js
@@ -0,0 +1,232 @@
+import { dsnToString } from './dsn.js';
+import { normalize } from './normalize.js';
+import { dropUndefinedKeys } from './object.js';
+
+/**
+ * Creates an envelope.
+ * Make sure to always explicitly provide the generic to this function
+ * so that the envelope types resolve correctly.
+ */
+function createEnvelope(headers, items = []) {
+ return [headers, items] ;
+}
+
+/**
+ * Add an item to an envelope.
+ * Make sure to always explicitly provide the generic to this function
+ * so that the envelope types resolve correctly.
+ */
+function addItemToEnvelope(envelope, newItem) {
+ const [headers, items] = envelope;
+ return [headers, [...items, newItem]] ;
+}
+
+/**
+ * Convenience function to loop through the items and item types of an envelope.
+ * (This function was mostly created because working with envelope types is painful at the moment)
+ *
+ * If the callback returns true, the rest of the items will be skipped.
+ */
+function forEachEnvelopeItem(
+ envelope,
+ callback,
+) {
+ const envelopeItems = envelope[1];
+
+ for (const envelopeItem of envelopeItems) {
+ const envelopeItemType = envelopeItem[0].type;
+ const result = callback(envelopeItem, envelopeItemType);
+
+ if (result) {
+ return true;
+ }
+ }
+
+ return false;
+}
+
+/**
+ * Returns true if the envelope contains any of the given envelope item types
+ */
+function envelopeContainsItemType(envelope, types) {
+ return forEachEnvelopeItem(envelope, (_, type) => types.includes(type));
+}
+
+/**
+ * Encode a string to UTF8.
+ */
+function encodeUTF8(input, textEncoder) {
+ const utf8 = textEncoder || new TextEncoder();
+ return utf8.encode(input);
+}
+
+/**
+ * Serializes an envelope.
+ */
+function serializeEnvelope(envelope, textEncoder) {
+ const [envHeaders, items] = envelope;
+
+ // Initially we construct our envelope as a string and only convert to binary chunks if we encounter binary data
+ let parts = JSON.stringify(envHeaders);
+
+ function append(next) {
+ if (typeof parts === 'string') {
+ parts = typeof next === 'string' ? parts + next : [encodeUTF8(parts, textEncoder), next];
+ } else {
+ parts.push(typeof next === 'string' ? encodeUTF8(next, textEncoder) : next);
+ }
+ }
+
+ for (const item of items) {
+ const [itemHeaders, payload] = item;
+
+ append(`\n${JSON.stringify(itemHeaders)}\n`);
+
+ if (typeof payload === 'string' || payload instanceof Uint8Array) {
+ append(payload);
+ } else {
+ let stringifiedPayload;
+ try {
+ stringifiedPayload = JSON.stringify(payload);
+ } catch (e) {
+ // In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.strinify()` still
+ // fails, we try again after normalizing it again with infinite normalization depth. This of course has a
+ // performance impact but in this case a performance hit is better than throwing.
+ stringifiedPayload = JSON.stringify(normalize(payload));
+ }
+ append(stringifiedPayload);
+ }
+ }
+
+ return typeof parts === 'string' ? parts : concatBuffers(parts);
+}
+
+function concatBuffers(buffers) {
+ const totalLength = buffers.reduce((acc, buf) => acc + buf.length, 0);
+
+ const merged = new Uint8Array(totalLength);
+ let offset = 0;
+ for (const buffer of buffers) {
+ merged.set(buffer, offset);
+ offset += buffer.length;
+ }
+
+ return merged;
+}
+
+/**
+ * Parses an envelope
+ */
+function parseEnvelope(
+ env,
+ textEncoder,
+ textDecoder,
+) {
+ let buffer = typeof env === 'string' ? textEncoder.encode(env) : env;
+
+ function readBinary(length) {
+ const bin = buffer.subarray(0, length);
+ // Replace the buffer with the remaining data excluding trailing newline
+ buffer = buffer.subarray(length + 1);
+ return bin;
+ }
+
+ function readJson() {
+ let i = buffer.indexOf(0xa);
+ // If we couldn't find a newline, we must have found the end of the buffer
+ if (i < 0) {
+ i = buffer.length;
+ }
+
+ return JSON.parse(textDecoder.decode(readBinary(i))) ;
+ }
+
+ const envelopeHeader = readJson();
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
+ const items = [];
+
+ while (buffer.length) {
+ const itemHeader = readJson();
+ const binaryLength = typeof itemHeader.length === 'number' ? itemHeader.length : undefined;
+
+ items.push([itemHeader, binaryLength ? readBinary(binaryLength) : readJson()]);
+ }
+
+ return [envelopeHeader, items];
+}
+
+/**
+ * Creates attachment envelope items
+ */
+function createAttachmentEnvelopeItem(
+ attachment,
+ textEncoder,
+) {
+ const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data, textEncoder) : attachment.data;
+
+ return [
+ dropUndefinedKeys({
+ type: 'attachment',
+ length: buffer.length,
+ filename: attachment.filename,
+ content_type: attachment.contentType,
+ attachment_type: attachment.attachmentType,
+ }),
+ buffer,
+ ];
+}
+
+const ITEM_TYPE_TO_DATA_CATEGORY_MAP = {
+ session: 'session',
+ sessions: 'session',
+ attachment: 'attachment',
+ transaction: 'transaction',
+ event: 'error',
+ client_report: 'internal',
+ user_report: 'default',
+ profile: 'profile',
+ replay_event: 'replay',
+ replay_recording: 'replay',
+ check_in: 'monitor',
+};
+
+/**
+ * Maps the type of an envelope item to a data category.
+ */
+function envelopeItemTypeToDataCategory(type) {
+ return ITEM_TYPE_TO_DATA_CATEGORY_MAP[type];
+}
+
+/** Extracts the minimal SDK info from from the metadata or an events */
+function getSdkMetadataForEnvelopeHeader(metadataOrEvent) {
+ if (!metadataOrEvent || !metadataOrEvent.sdk) {
+ return;
+ }
+ const { name, version } = metadataOrEvent.sdk;
+ return { name, version };
+}
+
+/**
+ * Creates event envelope headers, based on event, sdk info and tunnel
+ * Note: This function was extracted from the core package to make it available in Replay
+ */
+function createEventEnvelopeHeaders(
+ event,
+ sdkInfo,
+ tunnel,
+ dsn,
+) {
+ const dynamicSamplingContext = event.sdkProcessingMetadata && event.sdkProcessingMetadata.dynamicSamplingContext;
+ return {
+ event_id: event.event_id ,
+ sent_at: new Date().toISOString(),
+ ...(sdkInfo && { sdk: sdkInfo }),
+ ...(!!tunnel && { dsn: dsnToString(dsn) }),
+ ...(dynamicSamplingContext && {
+ trace: dropUndefinedKeys({ ...dynamicSamplingContext }),
+ }),
+ };
+}
+
+export { addItemToEnvelope, createAttachmentEnvelopeItem, createEnvelope, createEventEnvelopeHeaders, envelopeContainsItemType, envelopeItemTypeToDataCategory, forEachEnvelopeItem, getSdkMetadataForEnvelopeHeader, parseEnvelope, serializeEnvelope };
+//# sourceMappingURL=envelope.js.map