// Normalize the diagnostic index completely before committing an encrypted batch. function object(value){if(!value||typeof value!=='object'||Array.isArray(value))throw Error('Invalid OTLP object');return value;} function array(value){if(value===undefined)return [];if(!Array.isArray(value))throw Error('Invalid OTLP array');return value;} function time(value){if(typeof value!=='string'||!/^\d{1,20}$/.test(value))throw Error('Invalid span timestamp');const number=BigInt(value);if(number>18446744073709551615n)throw Error('Span timestamp overflow');return number;} export function normalizeCollectorBatch(signal,payload){ object(payload);const normalized={spans:[],logs:0,metrics:0}; if(signal==='traces')for(const resource of array(payload.resourceSpans))for(const scope of array(object(resource).scopeSpans))for(const entry of array(object(scope).spans)){ const span=object(entry);if(typeof span.traceId!=='string'||! /^[a-f0-9]{32}$/.test(span.traceId)||/^0+$/.test(span.traceId)||typeof span.spanId!=='string'||! /^[a-f0-9]{16}$/.test(span.spanId)||/^0+$/.test(span.spanId))throw Error('Invalid span identity'); if(span.parentSpanId!==undefined&&span.parentSpanId!==''&&(typeof span.parentSpanId!=='string'||! /^[a-f0-9]{16}$/.test(span.parentSpanId)))throw Error('Invalid parent span identity'); if(typeof span.name!=='string')throw Error('Invalid span name');const start=time(span.startTimeUnixNano),end=time(span.endTimeUnixNano),duration=end-start;if(duration<0n||duration>BigInt(Number.MAX_SAFE_INTEGER))throw Error('Invalid span duration'); const attributes=array(span.attributes);for(const attribute of attributes)object(attribute);const value=attributes.find(a=>a.key==='safetynet.operation')?.value?.stringValue; normalized.spans.push({traceId:span.traceId,spanId:span.spanId,parentSpanId:span.parentSpanId||null,name:span.name.slice(0,80),operation:typeof value==='string'?value.slice(0,80):'',durationMs:Number(duration)/1e6}); } else if(signal==='logs')for(const resource of array(payload.resourceLogs))for(const scope of array(object(resource).scopeLogs)){const records=array(object(scope).logRecords);for(const record of records)object(record);normalized.logs+=records.length;} else if(signal==='metrics'){for(const resource of array(payload.resourceMetrics))for(const scope of array(object(resource).scopeMetrics))for(const metric of array(object(scope).metrics))object(metric);normalized.metrics=1;} else throw Error('Unknown OTLP signal'); return normalized; }