forked from off-topic/apps.apple.com
init commit
This commit is contained in:
232
shared/logger/node_modules/@sentry/utils/esm/envelope.js
generated
vendored
Normal file
232
shared/logger/node_modules/@sentry/utils/esm/envelope.js
generated
vendored
Normal file
@@ -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
|
||||
Reference in New Issue
Block a user