UNPKG

@sentry/core

Version:
262 lines (225 loc) 7.44 kB
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 (e) { // 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', }; /** * 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