123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246 |
- Object.defineProperty(exports, '__esModule', { value: true });
- const dsn = require('./dsn.js');
- const normalize = require('./normalize.js');
- const object = require('./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.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 [
- object.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',
- feedback: 'feedback',
- // TODO: This is a temporary workaround until we have a proper data category for metrics
- statsd: 'unknown',
- };
- /**
- * 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$1,
- ) {
- const dynamicSamplingContext = event.sdkProcessingMetadata && 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: object.dropUndefinedKeys({ ...dynamicSamplingContext }),
- }),
- };
- }
- exports.addItemToEnvelope = addItemToEnvelope;
- exports.createAttachmentEnvelopeItem = createAttachmentEnvelopeItem;
- exports.createEnvelope = createEnvelope;
- exports.createEventEnvelopeHeaders = createEventEnvelopeHeaders;
- exports.envelopeContainsItemType = envelopeContainsItemType;
- exports.envelopeItemTypeToDataCategory = envelopeItemTypeToDataCategory;
- exports.forEachEnvelopeItem = forEachEnvelopeItem;
- exports.getSdkMetadataForEnvelopeHeader = getSdkMetadataForEnvelopeHeader;
- exports.parseEnvelope = parseEnvelope;
- exports.serializeEnvelope = serializeEnvelope;
- //# sourceMappingURL=envelope.js.map
|