autotel-devtools 20.0.1 → 21.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,10 +1,11 @@
1
+ import { i as asString, o as stringAttr, t as asObject } from "./json-fields-CPjKZ2WH.js";
1
2
  import { t as pickRoot } from "./trace-root-EHnvuA7f.js";
2
3
  import { t as getResourceName } from "./resource-utils-B4UVvfnH.js";
3
4
  import { createServer } from "node:http";
4
5
  import { WebSocket, WebSocketServer } from "ws";
5
6
  import { ingestAgentEvents, ingestAgentMetrics } from "autotel-agents";
6
- import { existsSync, readFileSync } from "node:fs";
7
- import { dirname, resolve } from "node:path";
7
+ import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
8
+ import path, { dirname, resolve } from "node:path";
8
9
  import { fileURLToPath } from "node:url";
9
10
  import protobuf from "protobufjs";
10
11
 
@@ -75,9 +76,9 @@ var ErrorAggregator = class {
75
76
  */
76
77
  extractErrorFromSpan(span, trace) {
77
78
  const exceptionEvent = span.events?.find((e) => e.name === "exception");
78
- const errorType = span.attributes["exception.type"] || span.attributes["error.type"] || exceptionEvent?.attributes?.["exception.type"] || "Error";
79
- const errorMessage = span.status.message || span.attributes["exception.message"] || span.attributes["error.message"] || "Unknown error";
80
- const stackTrace = span.attributes["exception.stacktrace"] || span.attributes["exception.stack"] || this.extractStackFromEvents(span);
79
+ const errorType = stringAttr(span.attributes, "exception.type", "error.type") ?? stringAttr(exceptionEvent?.attributes, "exception.type") ?? "Error";
80
+ const errorMessage = span.status.message || stringAttr(span.attributes, "exception.message", "error.message") || "Unknown error";
81
+ const stackTrace = stringAttr(span.attributes, "exception.stacktrace", "exception.stack", "error.stack") ?? this.extractStackFromEvents(span);
81
82
  return {
82
83
  traceId: trace.traceId,
83
84
  spanId: span.spanId,
@@ -87,7 +88,8 @@ var ErrorAggregator = class {
87
88
  error: {
88
89
  type: errorType,
89
90
  message: errorMessage,
90
- stackTrace
91
+ stackTrace,
92
+ fingerprint: stringAttr(span.attributes, "exception.fingerprint") ?? stringAttr(exceptionEvent?.attributes, "exception.fingerprint")
91
93
  },
92
94
  attributes: this.extractRelevantAttributes(span.attributes)
93
95
  };
@@ -98,7 +100,7 @@ var ErrorAggregator = class {
98
100
  extractStackFromEvents(span) {
99
101
  if (!span.events) return void 0;
100
102
  const exceptionEvent = span.events.find((e) => e.name === "exception");
101
- if (exceptionEvent?.attributes) return exceptionEvent.attributes["exception.stacktrace"] || exceptionEvent.attributes["exception.stack"];
103
+ if (exceptionEvent?.attributes) return stringAttr(exceptionEvent.attributes, "exception.stacktrace", "exception.stack");
102
104
  }
103
105
  /**
104
106
  * Extract relevant attributes for error context
@@ -127,6 +129,7 @@ var ErrorAggregator = class {
127
129
  * Uses error type + first N stack frames (normalized)
128
130
  */
129
131
  generateFingerprint(occurrence) {
132
+ if (occurrence.error.fingerprint) return occurrence.error.fingerprint;
130
133
  const parts = [occurrence.error.type];
131
134
  if (occurrence.error.stackTrace) {
132
135
  const frames = this.extractStackFrames(occurrence.error.stackTrace, this.options.stackFramesForFingerprint);
@@ -530,13 +533,28 @@ var DevtoolsServer = class {
530
533
  }
531
534
  };
532
535
 
536
+ //#endregion
537
+ //#region src/server/otlp-types.ts
538
+ /**
539
+ * An exporter's payload, read as the envelope it claims to be.
540
+ *
541
+ * SAFETY: this is the one place the receiver trusts the wire. Every field of
542
+ * every envelope above is optional, so a payload that is not what it claims
543
+ * reads back as empty arrays and undefined fields rather than throwing - which
544
+ * is what the callers below rely on when they find no spans to add.
545
+ */
546
+ function otlpEnvelope(payload) {
547
+ if (typeof payload !== "object" || payload === null) return void 0;
548
+ return payload;
549
+ }
550
+
533
551
  //#endregion
534
552
  //#region src/server/otlp.ts
535
553
  function resolveOtlpValue(v) {
536
554
  if (!v) return void 0;
537
555
  if (v.stringValue !== void 0) return v.stringValue;
538
556
  if (v.boolValue !== void 0) return v.boolValue;
539
- if (v.intValue !== void 0) return typeof v.intValue === "string" ? Number(v.intValue) : v.intValue;
557
+ if (v.intValue !== void 0) return Number(v.intValue);
540
558
  if (v.doubleValue !== void 0) return v.doubleValue;
541
559
  if (v.bytesValue !== void 0) return v.bytesValue;
542
560
  if (v.arrayValue?.values) return v.arrayValue.values.map(resolveOtlpValue);
@@ -548,6 +566,29 @@ function flattenAttributes(attrs) {
548
566
  for (const { key, value } of attrs) out[key] = resolveOtlpValue(value);
549
567
  return out;
550
568
  }
569
+ /**
570
+ * A log record's body: the text it carried, or the structure it carried when
571
+ * the sender used an OTLP kvlist or array rather than a string.
572
+ */
573
+ function logBody(body) {
574
+ const text = asString(body);
575
+ if (text !== void 0) return text;
576
+ if (body === void 0 || body === null) return "";
577
+ const structured = asObject(body);
578
+ if (!structured) return String(body);
579
+ return structured;
580
+ }
581
+ /**
582
+ * Attributes handed to the agent layer, whose `Attributes` is OTel's own -
583
+ * scalars and arrays of scalars, nothing nested.
584
+ *
585
+ * SAFETY: a coding agent's metrics and events carry scalar attributes only,
586
+ * so the two shapes agree in practice. A sender that nests one anyway is
587
+ * rendered by the Agents tab as whatever it is rather than being dropped.
588
+ */
589
+ function agentAttributes(attributes) {
590
+ return attributes;
591
+ }
551
592
  function nanoToMs(nano) {
552
593
  if (!nano) return 0;
553
594
  const ns = BigInt(nano);
@@ -555,19 +596,19 @@ function nanoToMs(nano) {
555
596
  const remNs = ns % 1000000n;
556
597
  return Number(ms) + Number(remNs) / 1e6;
557
598
  }
558
- const SPAN_KIND_MAP = {
559
- 0: "INTERNAL",
560
- 1: "INTERNAL",
561
- 2: "SERVER",
562
- 3: "CLIENT",
563
- 4: "PRODUCER",
564
- 5: "CONSUMER",
565
- SPAN_KIND_INTERNAL: "INTERNAL",
566
- SPAN_KIND_SERVER: "SERVER",
567
- SPAN_KIND_CLIENT: "CLIENT",
568
- SPAN_KIND_PRODUCER: "PRODUCER",
569
- SPAN_KIND_CONSUMER: "CONSUMER"
570
- };
599
+ const SPAN_KIND_MAP = /* @__PURE__ */ new Map([
600
+ [0, "INTERNAL"],
601
+ [1, "INTERNAL"],
602
+ [2, "SERVER"],
603
+ [3, "CLIENT"],
604
+ [4, "PRODUCER"],
605
+ [5, "CONSUMER"],
606
+ ["SPAN_KIND_INTERNAL", "INTERNAL"],
607
+ ["SPAN_KIND_SERVER", "SERVER"],
608
+ ["SPAN_KIND_CLIENT", "CLIENT"],
609
+ ["SPAN_KIND_PRODUCER", "PRODUCER"],
610
+ ["SPAN_KIND_CONSUMER", "CONSUMER"]
611
+ ]);
571
612
  function normalizeHexId(id) {
572
613
  if (!id) return "";
573
614
  if (/^[A-Za-z0-9+/=]+$/.test(id) && !/^[0-9a-f]+$/i.test(id) && (id.length === 12 || id.length === 24 || id.length === 28 || id.length === 44 || id.length === 48)) try {
@@ -576,15 +617,13 @@ function normalizeHexId(id) {
576
617
  return id;
577
618
  }
578
619
  function parseOtlpTraces(payload) {
579
- if (!payload || typeof payload !== "object") return [];
580
- const { resourceSpans } = payload;
581
- if (!Array.isArray(resourceSpans) || resourceSpans.length === 0) return [];
620
+ const resourceSpans = otlpEnvelope(payload)?.resourceSpans;
621
+ if (!resourceSpans || resourceSpans.length === 0) return [];
582
622
  const traceMap = /* @__PURE__ */ new Map();
583
623
  for (const rs of resourceSpans) {
584
624
  const resourceAttrs = flattenAttributes(rs.resource?.attributes);
585
625
  const service = String(resourceAttrs["service.name"] || "unknown");
586
- const scopeSpans = rs.scopeSpans || [];
587
- for (const ss of scopeSpans) {
626
+ for (const ss of rs.scopeSpans ?? []) {
588
627
  const scope = ss.scope?.name ? {
589
628
  name: ss.scope.name,
590
629
  version: ss.scope.version || void 0
@@ -603,7 +642,7 @@ function parseOtlpTraces(payload) {
603
642
  spanId: normalizeHexId(span.spanId),
604
643
  parentSpanId: normalizeHexId(span.parentSpanId) || void 0,
605
644
  name: span.name || "unknown",
606
- kind: SPAN_KIND_MAP[span.kind ?? 0] || "INTERNAL",
645
+ kind: SPAN_KIND_MAP.get(span.kind ?? 0) ?? "INTERNAL",
607
646
  startTime: startMs,
608
647
  endTime: endMs,
609
648
  duration: endMs - startMs,
@@ -615,12 +654,12 @@ function parseOtlpTraces(payload) {
615
654
  code: status,
616
655
  message: span.status?.message
617
656
  },
618
- events: (span.events || []).map((e) => ({
657
+ events: (span.events ?? []).map((e) => ({
619
658
  name: e.name || "",
620
659
  timestamp: nanoToMs(e.timeUnixNano),
621
660
  attributes: flattenAttributes(e.attributes)
622
661
  })),
623
- links: (span.links || []).map((l) => ({
662
+ links: (span.links ?? []).map((l) => ({
624
663
  traceId: normalizeHexId(l.traceId),
625
664
  spanId: normalizeHexId(l.spanId),
626
665
  attributes: flattenAttributes(l.attributes)
@@ -643,7 +682,7 @@ function parseOtlpTraces(payload) {
643
682
  const startTime = Math.min(...sorted.map((s) => s.startTime));
644
683
  const endTime = Math.max(...sorted.map((s) => s.endTime));
645
684
  const hasError = sorted.some((s) => s.status.code === "ERROR");
646
- traces.push({
685
+ const trace = {
647
686
  traceId,
648
687
  correlationId: traceId.slice(0, 16),
649
688
  rootSpan,
@@ -652,20 +691,20 @@ function parseOtlpTraces(payload) {
652
691
  endTime,
653
692
  duration: endTime - startTime,
654
693
  status: hasError ? "ERROR" : "OK",
655
- service,
656
- ...partial ? { partial: true } : {}
657
- });
694
+ service
695
+ };
696
+ if (partial) trace.partial = true;
697
+ traces.push(trace);
658
698
  }
659
699
  return traces;
660
700
  }
661
701
  function parseOtlpLogs(payload) {
662
- if (!payload || typeof payload !== "object") return [];
663
- const { resourceLogs } = payload;
664
- if (!Array.isArray(resourceLogs)) return [];
702
+ const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
703
+ if (!resourceLogs) return [];
665
704
  const logs = [];
666
705
  for (const rl of resourceLogs) {
667
706
  const resourceAttrs = flattenAttributes(rl.resource?.attributes);
668
- for (const sl of rl.scopeLogs || []) for (const rec of sl.logRecords || []) {
707
+ for (const sl of rl.scopeLogs ?? []) for (const rec of sl.logRecords ?? []) {
669
708
  const timestamp = nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano);
670
709
  const traceId = normalizeHexId(rec.traceId) || void 0;
671
710
  const spanId = normalizeHexId(rec.spanId) || void 0;
@@ -677,7 +716,7 @@ function parseOtlpLogs(payload) {
677
716
  resourceName: getResourceName(resourceAttrs),
678
717
  severityText: rec.severityText,
679
718
  severityNumber: rec.severityNumber,
680
- body: typeof body === "string" ? body : body,
719
+ body: logBody(body),
681
720
  timestamp,
682
721
  attributes: flattenAttributes(rec.attributes),
683
722
  resource: resourceAttrs
@@ -687,11 +726,10 @@ function parseOtlpLogs(payload) {
687
726
  return logs;
688
727
  }
689
728
  function countOtlpMetrics(payload) {
690
- if (!payload || typeof payload !== "object") return 0;
691
- const { resourceMetrics } = payload;
692
- if (!Array.isArray(resourceMetrics)) return 0;
729
+ const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
730
+ if (!resourceMetrics) return 0;
693
731
  let count = 0;
694
- for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics || []) count += (sm.metrics || []).length;
732
+ for (const rm of resourceMetrics) for (const sm of rm.scopeMetrics ?? []) count += (sm.metrics ?? []).length;
695
733
  return count;
696
734
  }
697
735
  function extractDataPoints(metric) {
@@ -701,14 +739,14 @@ function extractDataPoints(metric) {
701
739
  const value = dp.asDouble !== void 0 ? Number(dp.asDouble) : dp.asInt !== void 0 ? Number(dp.asInt) : 0;
702
740
  points.push({
703
741
  value,
704
- attributes: flattenAttributes(dp.attributes),
742
+ attributes: agentAttributes(flattenAttributes(dp.attributes)),
705
743
  timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
706
744
  });
707
745
  }
708
746
  const histPoints = metric.histogram?.dataPoints;
709
747
  if (Array.isArray(histPoints)) for (const dp of histPoints) points.push({
710
748
  value: dp.count !== void 0 ? Number(dp.count) : 0,
711
- attributes: flattenAttributes(dp.attributes),
749
+ attributes: agentAttributes(flattenAttributes(dp.attributes)),
712
750
  timestamp: nanoToMs(dp.timeUnixNano || dp.startTimeUnixNano)
713
751
  });
714
752
  return points;
@@ -724,19 +762,18 @@ function readTemporality(metric) {
724
762
  if (raw === 1 || raw === "AGGREGATION_TEMPORALITY_DELTA") return "delta";
725
763
  }
726
764
  function parseOtlpMetrics(payload) {
727
- if (!payload || typeof payload !== "object") return [];
728
- const { resourceMetrics } = payload;
729
- if (!Array.isArray(resourceMetrics)) return [];
765
+ const resourceMetrics = otlpEnvelope(payload)?.resourceMetrics;
766
+ if (!resourceMetrics) return [];
730
767
  const records = [];
731
768
  for (const rm of resourceMetrics) {
732
- const resource = flattenAttributes(rm.resource?.attributes);
733
- for (const sm of rm.scopeMetrics || []) {
769
+ const resource = agentAttributes(flattenAttributes(rm.resource?.attributes));
770
+ for (const sm of rm.scopeMetrics ?? []) {
734
771
  const scope = sm.scope?.name ? {
735
772
  name: sm.scope.name,
736
773
  version: sm.scope.version || void 0
737
774
  } : void 0;
738
- for (const metric of sm.metrics || []) records.push({
739
- name: metric.name,
775
+ for (const metric of sm.metrics ?? []) records.push({
776
+ name: metric.name ?? "",
740
777
  unit: metric.unit || void 0,
741
778
  description: metric.description || void 0,
742
779
  temporality: readTemporality(metric),
@@ -755,20 +792,19 @@ function parseOtlpMetrics(payload) {
755
792
  * `parseOtlpLogs`, which feeds the generic Logs tab.
756
793
  */
757
794
  function parseOtlpAgentEvents(payload) {
758
- if (!payload || typeof payload !== "object") return [];
759
- const { resourceLogs } = payload;
760
- if (!Array.isArray(resourceLogs)) return [];
795
+ const resourceLogs = otlpEnvelope(payload)?.resourceLogs;
796
+ if (!resourceLogs) return [];
761
797
  const events = [];
762
798
  for (const rl of resourceLogs) {
763
- const resource = flattenAttributes(rl.resource?.attributes);
764
- for (const sl of rl.scopeLogs || []) {
799
+ const resource = agentAttributes(flattenAttributes(rl.resource?.attributes));
800
+ for (const sl of rl.scopeLogs ?? []) {
765
801
  const scope = sl.scope?.name ? {
766
802
  name: sl.scope.name,
767
803
  version: sl.scope.version || void 0
768
804
  } : void 0;
769
- for (const rec of sl.logRecords || []) {
770
- const attributes = flattenAttributes(rec.attributes);
771
- const eventName = typeof rec.eventName === "string" && rec.eventName || String(attributes["event.name"] ?? "");
805
+ for (const rec of sl.logRecords ?? []) {
806
+ const attributes = agentAttributes(flattenAttributes(rec.attributes));
807
+ const eventName = rec.eventName || String(attributes["event.name"] ?? "");
772
808
  events.push({
773
809
  eventName,
774
810
  timestamp: nanoToMs(rec.timeUnixNano || rec.observedTimeUnixNano),
@@ -1121,6 +1157,98 @@ async function probePortHolder(host, port, timeoutMs = 500) {
1121
1157
  }
1122
1158
  }
1123
1159
 
1160
+ //#endregion
1161
+ //#region src/server/source-file.ts
1162
+ /** Refuse to slurp something huge just because a span named it. */
1163
+ const MAX_BYTES = 2e6;
1164
+ const DISABLED = /* @__PURE__ */ new Set([
1165
+ "false",
1166
+ "0",
1167
+ "off",
1168
+ "no",
1169
+ ""
1170
+ ]);
1171
+ /**
1172
+ * Decide what `GET /source` may read, from `AUTOTEL_DEVTOOLS_SOURCE_ROOT`.
1173
+ *
1174
+ * Defaults **on**, at the working directory: devtools is a local tool whose
1175
+ * whole point is showing you your own code, and requiring a flag for that would
1176
+ * mean nobody ever sees the feature. The blast radius stays small because two
1177
+ * other things still hold — the receiver is bound to loopback, and nothing
1178
+ * outside this directory is reachable. Set the variable to `false` to turn it
1179
+ * off outright.
1180
+ *
1181
+ * A non-loopback bind (`--host 0.0.0.0`) removes the first of those, and the
1182
+ * Origin guard does not replace it: a request with no `Origin` at all — any
1183
+ * `curl` on the network — passes. The root holds whatever else lives in the
1184
+ * project, `.env` included, so the default flips to **off** there. An explicit
1185
+ * root is still honoured: exposing it on purpose is the caller's call.
1186
+ */
1187
+ function resolveSourceRoot(configured, cwd, loopbackOnly = true) {
1188
+ if (configured === void 0) return loopbackOnly ? cwd : void 0;
1189
+ if (DISABLED.has(configured.trim().toLowerCase())) return void 0;
1190
+ return configured;
1191
+ }
1192
+ /**
1193
+ * Resolve `requested` against `root`, or return `null` if it escapes.
1194
+ *
1195
+ * Containment is judged on **real** paths so a symlink inside the root that
1196
+ * points outside it is rejected — lexical `..` stripping alone cannot see that.
1197
+ * The value returned is the *lexical* resolution, because the real one differs
1198
+ * from the caller's path whenever an ancestor is a symlink (on macOS both
1199
+ * `/tmp` and `/var` are), and a caller comparing paths should not have to know.
1200
+ */
1201
+ function resolveWithinRoot(root, requested) {
1202
+ const lexicalRoot = path.resolve(root);
1203
+ const realRoot = safeRealpath(lexicalRoot);
1204
+ if (realRoot === null) return null;
1205
+ const lexicalTarget = path.resolve(lexicalRoot, requested);
1206
+ const realTarget = safeRealpath(lexicalTarget);
1207
+ if (realTarget === null) return null;
1208
+ if (!isInside(realRoot, realTarget)) return null;
1209
+ return lexicalTarget;
1210
+ }
1211
+ /** True when `target` is `root` itself or sits beneath it. */
1212
+ function isInside(root, target) {
1213
+ if (target === root) return true;
1214
+ return target.startsWith(root.endsWith(path.sep) ? root : root + path.sep);
1215
+ }
1216
+ function safeRealpath(p) {
1217
+ try {
1218
+ return realpathSync(p);
1219
+ } catch {
1220
+ return null;
1221
+ }
1222
+ }
1223
+ /**
1224
+ * Read `context` lines either side of `line` from a file inside `root`.
1225
+ * Returns `null` when the path escapes the root, is not a readable file, or is
1226
+ * too large — the caller cannot distinguish those, which is the point.
1227
+ */
1228
+ function readSourceWindow(root, requested, line, context) {
1229
+ const resolved = resolveWithinRoot(root, requested);
1230
+ if (resolved === null) return null;
1231
+ let text;
1232
+ try {
1233
+ const stat = statSync(resolved);
1234
+ if (!stat.isFile() || stat.size > MAX_BYTES) return null;
1235
+ text = readFileSync(resolved, "utf8");
1236
+ } catch {
1237
+ return null;
1238
+ }
1239
+ const all = text.split("\n");
1240
+ if (all.at(-1) === "") all.pop();
1241
+ const startLine = Math.max(1, line - context);
1242
+ const endLine = Math.min(all.length, line + context);
1243
+ if (startLine > all.length) return null;
1244
+ return {
1245
+ file: path.relative(path.resolve(root), resolved),
1246
+ line,
1247
+ startLine,
1248
+ lines: all.slice(startLine - 1, endLine)
1249
+ };
1250
+ }
1251
+
1124
1252
  //#endregion
1125
1253
  //#region src/server/http.ts
1126
1254
  function sendOtlpError(res, req, e) {
@@ -1184,6 +1312,7 @@ function getWidgetJs() {
1184
1312
  }
1185
1313
  function attachDevtoolsRoutes(httpServer, devtools, options = {}) {
1186
1314
  const loopbackOnly = options.loopbackOnly ?? true;
1315
+ const sourceRoot = options.sourceRoot;
1187
1316
  const fullpageHtml = renderFullpageHtml(options.title);
1188
1317
  httpServer.on("request", async (req, res) => {
1189
1318
  if (req.headers.upgrade?.toLowerCase() === "websocket") return;
@@ -1224,6 +1353,31 @@ function attachDevtoolsRoutes(httpServer, devtools, options = {}) {
1224
1353
  res.end(DEVTOOLS_FAVICON_SVG);
1225
1354
  return;
1226
1355
  }
1356
+ if (req.method === "GET" && url.split("?")[0] === "/source") {
1357
+ if (!sourceRoot) {
1358
+ sendJson(res, 404, { error: "Not found" });
1359
+ return;
1360
+ }
1361
+ if (!allowSensitiveRequest(req.headers, loopbackOnly)) {
1362
+ sendJson(res, 403, { error: "Forbidden" });
1363
+ return;
1364
+ }
1365
+ const query = new URL(url, "http://localhost").searchParams;
1366
+ const file = query.get("file");
1367
+ const line = Number(query.get("line"));
1368
+ const context = Math.min(Math.max(Number(query.get("context") ?? 5) || 0, 0), 50);
1369
+ if (!file || !Number.isInteger(line) || line < 1) {
1370
+ sendJson(res, 400, { error: "file and a positive integer line are required" });
1371
+ return;
1372
+ }
1373
+ const window = readSourceWindow(sourceRoot, file, line, context);
1374
+ if (window === null) {
1375
+ sendJson(res, 404, { error: "Not found" });
1376
+ return;
1377
+ }
1378
+ sendJson(res, 200, { ...window });
1379
+ return;
1380
+ }
1227
1381
  if (req.method === "GET" && url === "/healthz") {
1228
1382
  sendJson(res, 200, {
1229
1383
  ok: true,
@@ -1296,4 +1450,4 @@ function createDevtoolsHttpServer(devtools, _options = {}) {
1296
1450
  }
1297
1451
 
1298
1452
  //#endregion
1299
- export { appendWithLimit as _, decodeOtlpLogsRequest as a, ErrorAggregator as b, isProtobufContentType as c, DevtoolsServer as d, allowSensitiveRequest as f, appendManyWithLimit as g, originIsLoopback as h, probePortHolder as i, parseOtlpLogs as l, isLoopbackHostname as m, createDevtoolsHttpServer as n, decodeOtlpMetricsRequest as o, hostHeaderIsLoopback as p, DEVTOOLS_IDENTITY as r, decodeOtlpTraceRequest as s, attachDevtoolsRoutes as t, parseOtlpTraces as u, applyTelemetryLimits as v, resolveTelemetryLimits as y };
1453
+ export { appendManyWithLimit as _, probePortHolder as a, resolveTelemetryLimits as b, decodeOtlpTraceRequest as c, parseOtlpTraces as d, DevtoolsServer as f, originIsLoopback as g, isLoopbackHostname as h, DEVTOOLS_IDENTITY as i, isProtobufContentType as l, hostHeaderIsLoopback as m, createDevtoolsHttpServer as n, decodeOtlpLogsRequest as o, allowSensitiveRequest as p, resolveSourceRoot as r, decodeOtlpMetricsRequest as s, attachDevtoolsRoutes as t, parseOtlpLogs as u, appendWithLimit as v, ErrorAggregator as x, applyTelemetryLimits as y };