{"version":3,"file":"utils.mjs","names":[],"sources":["../../src/baggage/utils.ts"],"sourcesContent":["/*\n * Copyright The OpenTelemetry Authors\n * SPDX-License-Identifier: Apache-2.0\n */\nimport type {\n  Baggage,\n  BaggageEntry,\n  BaggageEntryMetadata,\n} from '@opentelemetry/api';\nimport { baggageEntryMetadataFromString } from '@opentelemetry/api';\nimport {\n  BAGGAGE_ITEMS_SEPARATOR,\n  BAGGAGE_PROPERTIES_SEPARATOR,\n  BAGGAGE_KEY_PAIR_SEPARATOR,\n  BAGGAGE_MAX_TOTAL_LENGTH,\n  BAGGAGE_MAX_NAME_VALUE_PAIRS,\n  BAGGAGE_MAX_PER_NAME_VALUE_PAIRS,\n} from './constants';\n\ntype ParsedBaggageKeyValue = {\n  key: string;\n  value: string;\n  metadata: BaggageEntryMetadata | undefined;\n};\n\nexport function serializeKeyPairs(keyPairs: string[]): string {\n  return keyPairs.reduce((hValue: string, current: string) => {\n    const value = `${hValue}${\n      hValue !== '' ? BAGGAGE_ITEMS_SEPARATOR : ''\n    }${current}`;\n    return value.length > BAGGAGE_MAX_TOTAL_LENGTH ? hValue : value;\n  }, '');\n}\n\nexport function getKeyPairs(baggage: Baggage): string[] {\n  return baggage.getAllEntries().map(([key, value]) => {\n    let entry = `${encodeURIComponent(key)}=${encodeURIComponent(value.value)}`;\n\n    // include opaque metadata if provided\n    // NOTE: we intentionally don't URI-encode the metadata - that responsibility falls on the metadata implementation\n    if (value.metadata !== undefined) {\n      entry += BAGGAGE_PROPERTIES_SEPARATOR + value.metadata.toString();\n    }\n\n    return entry;\n  });\n}\n\nexport function parsePairKeyValue(\n  entry: string\n): ParsedBaggageKeyValue | undefined {\n  if (!entry) return;\n  const metadataSeparatorIndex = entry.indexOf(BAGGAGE_PROPERTIES_SEPARATOR);\n  const keyPairPart =\n    metadataSeparatorIndex === -1\n      ? entry\n      : entry.substring(0, metadataSeparatorIndex);\n\n  const separatorIndex = keyPairPart.indexOf(BAGGAGE_KEY_PAIR_SEPARATOR);\n  if (separatorIndex <= 0) return;\n\n  const rawKey = keyPairPart.substring(0, separatorIndex).trim();\n  const rawValue = keyPairPart.substring(separatorIndex + 1).trim();\n\n  if (!rawKey || !rawValue) return;\n  let key: string;\n  let value: string;\n  try {\n    key = decodeURIComponent(rawKey);\n    value = decodeURIComponent(rawValue);\n  } catch {\n    return;\n  }\n\n  let metadata;\n  if (\n    metadataSeparatorIndex !== -1 &&\n    metadataSeparatorIndex < entry.length - 1\n  ) {\n    const metadataString = entry.substring(metadataSeparatorIndex + 1);\n    metadata = baggageEntryMetadataFromString(metadataString);\n  }\n\n  return { key, value, metadata };\n}\n\n/**\n * Parses a single baggage header string into the provided record, applying limits defined in this package.\n * Uses indexOf/substring in a while loop to avoid allocating a full array of split entries.\n * Returns the updated pair count so callers can track totals across multiple header values.\n */\nexport function parseBaggageHeaderString(\n  value: string,\n  baggage: Record<string, BaggageEntry>,\n  count: number,\n  totalSize: number\n): [count: number, totalSize: number] {\n  let start = 0;\n  while (start < value.length && count < BAGGAGE_MAX_NAME_VALUE_PAIRS) {\n    const end = value.indexOf(BAGGAGE_ITEMS_SEPARATOR, start);\n    const entryEnd = end === -1 ? value.length : end;\n    const entryLength = entryEnd - start;\n\n    if (entryLength <= BAGGAGE_MAX_PER_NAME_VALUE_PAIRS) {\n      const keyPair = parsePairKeyValue(value.substring(start, entryEnd));\n      if (keyPair) {\n        // Comma separator is counted for every accepted entry after the first\n        const entrySize = (count === 0 ? 0 : 1) + entryLength;\n        if (totalSize + entrySize > BAGGAGE_MAX_TOTAL_LENGTH) break;\n        baggage[keyPair.key] = keyPair.metadata\n          ? { value: keyPair.value, metadata: keyPair.metadata }\n          : { value: keyPair.value };\n        count++;\n        totalSize += entrySize;\n      }\n    }\n\n    if (end === -1) break;\n    start = end + 1;\n  }\n  return [count, totalSize];\n}\n\n/**\n * Parse a string serialized in the baggage HTTP Format (without metadata):\n * https://github.com/w3c/baggage/blob/master/baggage/HTTP_HEADER_FORMAT.md\n */\nexport function parseKeyPairsIntoRecord(\n  value?: string\n): Record<string, string> {\n  const result: Record<string, string> = {};\n\n  if (typeof value === 'string' && value.length > 0) {\n    value.split(BAGGAGE_ITEMS_SEPARATOR).forEach(entry => {\n      const keyPair = parsePairKeyValue(entry);\n\n      if (keyPair !== undefined && keyPair.value.length > 0) {\n        result[keyPair.key] = keyPair.value;\n      }\n    });\n  }\n\n  return result;\n}\n"],"mappings":";;;AAyBA,SAAgB,kBAAkB,UAA4B;CAC5D,OAAO,SAAS,QAAQ,QAAgB,YAAoB;EAC1D,MAAM,QAAQ,GAAG,SACf,WAAW,KAAA,MAA+B,KACzC;EACH,OAAO,MAAM,SAAA,OAAoC,SAAS;CAC5D,GAAG,EAAE;AACP;AAEA,SAAgB,YAAY,SAA4B;CACtD,OAAO,QAAQ,cAAc,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW;EACnD,IAAI,QAAQ,GAAG,mBAAmB,GAAG,EAAE,GAAG,mBAAmB,MAAM,KAAK;EAIxE,IAAI,MAAM,aAAa,KAAA,GACrB,SAAA,MAAwC,MAAM,SAAS,SAAS;EAGlE,OAAO;CACT,CAAC;AACH;AAEA,SAAgB,kBACd,OACmC;CACnC,IAAI,CAAC,OAAO;CACZ,MAAM,yBAAyB,MAAM,QAAA,GAAoC;CACzE,MAAM,cACJ,2BAA2B,KACvB,QACA,MAAM,UAAU,GAAG,sBAAsB;CAE/C,MAAM,iBAAiB,YAAY,QAAA,GAAkC;CACrE,IAAI,kBAAkB,GAAG;CAEzB,MAAM,SAAS,YAAY,UAAU,GAAG,cAAc,CAAC,CAAC,KAAK;CAC7D,MAAM,WAAW,YAAY,UAAU,iBAAiB,CAAC,CAAC,CAAC,KAAK;CAEhE,IAAI,CAAC,UAAU,CAAC,UAAU;CAC1B,IAAI;CACJ,IAAI;CACJ,IAAI;EACF,MAAM,mBAAmB,MAAM;EAC/B,QAAQ,mBAAmB,QAAQ;CACrC,QAAQ;EACN;CACF;CAEA,IAAI;CACJ,IACE,2BAA2B,MAC3B,yBAAyB,MAAM,SAAS,GACxC;EACA,MAAM,iBAAiB,MAAM,UAAU,yBAAyB,CAAC;EACjE,WAAW,+BAA+B,cAAc;CAC1D;CAEA,OAAO;EAAE;EAAK;EAAO;CAAS;AAChC;;;;;;AAOA,SAAgB,yBACd,OACA,SACA,OACA,WACoC;CACpC,IAAI,QAAQ;CACZ,OAAO,QAAQ,MAAM,UAAU,QAAA,KAAsC;EACnE,MAAM,MAAM,MAAM,QAAA,KAAiC,KAAK;EACxD,MAAM,WAAW,QAAQ,KAAK,MAAM,SAAS;EAC7C,MAAM,cAAc,WAAW;EAE/B,IAAI,eAAA,MAAiD;GACnD,MAAM,UAAU,kBAAkB,MAAM,UAAU,OAAO,QAAQ,CAAC;GAClE,IAAI,SAAS;IAEX,MAAM,aAAa,UAAU,IAAI,IAAI,KAAK;IAC1C,IAAI,YAAY,YAAA,MAAsC;IACtD,QAAQ,QAAQ,OAAO,QAAQ,WAC3B;KAAE,OAAO,QAAQ;KAAO,UAAU,QAAQ;IAAS,IACnD,EAAE,OAAO,QAAQ,MAAM;IAC3B;IACA,aAAa;GACf;EACF;EAEA,IAAI,QAAQ,IAAI;EAChB,QAAQ,MAAM;CAChB;CACA,OAAO,CAAC,OAAO,SAAS;AAC1B;;;;;AAMA,SAAgB,wBACd,OACwB;CACxB,MAAM,SAAiC,CAAC;CAExC,IAAI,OAAO,UAAU,YAAY,MAAM,SAAS,GAC9C,MAAM,MAAA,GAA6B,CAAC,CAAC,SAAQ,UAAS;EACpD,MAAM,UAAU,kBAAkB,KAAK;EAEvC,IAAI,YAAY,KAAA,KAAa,QAAQ,MAAM,SAAS,GAClD,OAAO,QAAQ,OAAO,QAAQ;CAElC,CAAC;CAGH,OAAO;AACT"}