Some checks failed
Build & Deploy / 🔍 Prepare (push) Successful in 20s
Build & Deploy / 🧪 QA (push) Failing after 34s
Build & Deploy / 🏗️ Build (push) Has started running
Build & Deploy / 🚀 Deploy (push) Has been cancelled
Build & Deploy / 🧪 Smoke Test (push) Has been cancelled
Build & Deploy / ⚡ Lighthouse (push) Has been cancelled
Build & Deploy / 🔔 Notify (push) Has been cancelled
264 lines
7.3 KiB
Plaintext
264 lines
7.3 KiB
Plaintext
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
|
|
const carrier = require('../carrier.js');
|
|
const dsn = require('./dsn.js');
|
|
const normalize = require('./normalize.js');
|
|
const worldwide = require('./worldwide.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 array.
|
|
*/
|
|
function encodeUTF8(input) {
|
|
const carrier$1 = carrier.getSentryCarrier(worldwide.GLOBAL_OBJ);
|
|
return carrier$1.encodePolyfill ? carrier$1.encodePolyfill(input) : new TextEncoder().encode(input);
|
|
}
|
|
|
|
/**
|
|
* Decode a UTF8 array to string.
|
|
*/
|
|
function decodeUTF8(input) {
|
|
const carrier$1 = carrier.getSentryCarrier(worldwide.GLOBAL_OBJ);
|
|
return carrier$1.decodePolyfill ? carrier$1.decodePolyfill(input) : new TextDecoder().decode(input);
|
|
}
|
|
|
|
/**
|
|
* Serializes an envelope.
|
|
*/
|
|
function serializeEnvelope(envelope) {
|
|
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), next];
|
|
} else {
|
|
parts.push(typeof next === 'string' ? encodeUTF8(next) : 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 {
|
|
// In case, despite all our efforts to keep `payload` circular-dependency-free, `JSON.stringify()` 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.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) {
|
|
let buffer = typeof env === 'string' ? encodeUTF8(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(decodeUTF8(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 envelope item for a single span
|
|
*/
|
|
function createSpanEnvelopeItem(spanJson) {
|
|
const spanHeaders = {
|
|
type: 'span',
|
|
};
|
|
|
|
return [spanHeaders, spanJson];
|
|
}
|
|
|
|
/**
|
|
* Creates attachment envelope items
|
|
*/
|
|
function createAttachmentEnvelopeItem(attachment) {
|
|
const buffer = typeof attachment.data === 'string' ? encodeUTF8(attachment.data) : attachment.data;
|
|
|
|
return [
|
|
{
|
|
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',
|
|
profile_chunk: 'profile',
|
|
replay_event: 'replay',
|
|
replay_recording: 'replay',
|
|
check_in: 'monitor',
|
|
feedback: 'feedback',
|
|
span: 'span',
|
|
raw_security: 'security',
|
|
log: 'log_item',
|
|
metric: 'metric',
|
|
trace_metric: 'metric',
|
|
};
|
|
|
|
/**
|
|
* 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 the metadata or an events */
|
|
function getSdkMetadataForEnvelopeHeader(metadataOrEvent) {
|
|
if (!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$1,
|
|
) {
|
|
const dynamicSamplingContext = event.sdkProcessingMetadata?.dynamicSamplingContext;
|
|
return {
|
|
event_id: event.event_id ,
|
|
sent_at: new Date().toISOString(),
|
|
...(sdkInfo && { sdk: sdkInfo }),
|
|
...(!!tunnel && dsn$1 && { dsn: dsn.dsnToString(dsn$1) }),
|
|
...(dynamicSamplingContext && {
|
|
trace: dynamicSamplingContext,
|
|
}),
|
|
};
|
|
}
|
|
|
|
exports.addItemToEnvelope = addItemToEnvelope;
|
|
exports.createAttachmentEnvelopeItem = createAttachmentEnvelopeItem;
|
|
exports.createEnvelope = createEnvelope;
|
|
exports.createEventEnvelopeHeaders = createEventEnvelopeHeaders;
|
|
exports.createSpanEnvelopeItem = createSpanEnvelopeItem;
|
|
exports.envelopeContainsItemType = envelopeContainsItemType;
|
|
exports.envelopeItemTypeToDataCategory = envelopeItemTypeToDataCategory;
|
|
exports.forEachEnvelopeItem = forEachEnvelopeItem;
|
|
exports.getSdkMetadataForEnvelopeHeader = getSdkMetadataForEnvelopeHeader;
|
|
exports.parseEnvelope = parseEnvelope;
|
|
exports.serializeEnvelope = serializeEnvelope;
|
|
//# sourceMappingURL=envelope.js.map
|