@mastra/observability 1.21.0-alpha.1 → 1.21.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.
package/dist/index.cjs CHANGED
@@ -16,7 +16,7 @@ var __copyProps = (to, from, except, desc) => {
16
16
  }
17
17
  return to;
18
18
  };
19
- var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", {
20
20
  value: mod,
21
21
  enumerable: true
22
22
  }) : target, mod));
@@ -77,9 +77,7 @@ function routeToHandler(handler, event, logger) {
77
77
  }), handler.name, "score", logger);
78
78
  }
79
79
  break;
80
- case "feedback":
81
- if (handler.onFeedbackEvent) return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
82
- break;
80
+ case "feedback": if (handler.onFeedbackEvent) return catchAsyncResult(handler.onFeedbackEvent(event), handler.name, "feedback", logger);
83
81
  }
84
82
  } catch (err) {
85
83
  logger.error(`[Observability] Handler error [handler=${handler.name}]:`, err);
@@ -228,7 +226,7 @@ const VALUE_STRIP_KEYS = /* @__PURE__ */ new Set([
228
226
  const DEFAULT_DEEP_CLEAN_OPTIONS = Object.freeze({
229
227
  keysToStrip: [],
230
228
  maxDepth: 8,
231
- maxStringLength: 128 * 1024,
229
+ maxStringLength: 131072,
232
230
  maxArrayLength: 50,
233
231
  maxObjectKeys: 50
234
232
  });
@@ -1302,8 +1300,8 @@ function isRecord(value) {
1302
1300
  //#endregion
1303
1301
  //#region src/metrics/pricing-registry.ts
1304
1302
  const DATA_FILE_NAME = "pricing-data.json";
1305
- const REFRESH_INTERVAL_MS = 1440 * 60 * 1e3;
1306
- const MIN_REFRESH_ATTEMPT_INTERVAL_MS = 3600 * 1e3;
1303
+ const REFRESH_INTERVAL_MS = 864e5;
1304
+ const MIN_REFRESH_ATTEMPT_INTERVAL_MS = 36e5;
1307
1305
  const REFRESH_TIMEOUT_MS = 5e3;
1308
1306
  const CACHE_FILE = () => path.default.join(os.default.homedir(), ".cache", "mastra", "pricing-data.json");
1309
1307
  const CACHE_VERSION = 1;
@@ -2845,6 +2843,26 @@ var ModelSpanTracker = class {
2845
2843
  this.#stepIndex++;
2846
2844
  }
2847
2845
  /**
2846
+ * A suspended step emits no step-finish; its suspension chunk carries the
2847
+ * step usage instead. Close MODEL_INFERENCE and MODEL_STEP with that usage so
2848
+ * the suspended call is not reported without tokens.
2849
+ */
2850
+ #endSuspendedStep(chunk) {
2851
+ if (chunk.type !== "tool-call-suspended" && chunk.type !== "tool-call-approval") return;
2852
+ const usage = chunk.payload.usage;
2853
+ if (!usage) return;
2854
+ this.#inModelResponse = false;
2855
+ this.#endStepSpan({
2856
+ output: { usage },
2857
+ stepResult: {
2858
+ reason: "suspended",
2859
+ isContinued: false,
2860
+ warnings: []
2861
+ },
2862
+ metadata: {}
2863
+ });
2864
+ }
2865
+ /**
2848
2866
  * Returns the parent span for chunks. Chunks parent under MODEL_INFERENCE
2849
2867
  * (the provider call) when available, falling back to MODEL_STEP only if
2850
2868
  * startStep() was bypassed.
@@ -2942,9 +2960,7 @@ var ModelSpanTracker = class {
2942
2960
  if (this.#currentChunkType !== "text") this.#startChunkSpan("text");
2943
2961
  this.#appendToAccumulator("text", chunk.payload.text);
2944
2962
  break;
2945
- case "text-end":
2946
- this.#endChunkSpan();
2947
- break;
2963
+ case "text-end": this.#endChunkSpan();
2948
2964
  }
2949
2965
  }
2950
2966
  /**
@@ -2959,9 +2975,7 @@ var ModelSpanTracker = class {
2959
2975
  if (this.#currentChunkType !== "reasoning") this.#startChunkSpan("reasoning");
2960
2976
  this.#appendToAccumulator("text", chunk.payload.text);
2961
2977
  break;
2962
- case "reasoning-end":
2963
- this.#endChunkSpan();
2964
- break;
2978
+ case "reasoning-end": this.#endChunkSpan();
2965
2979
  }
2966
2980
  }
2967
2981
  /**
@@ -3004,9 +3018,7 @@ var ModelSpanTracker = class {
3004
3018
  case "object":
3005
3019
  if (this.#currentChunkType !== "object") this.#startChunkSpan("object");
3006
3020
  break;
3007
- case "object-result":
3008
- this.#endChunkSpan(chunk.object);
3009
- break;
3021
+ case "object-result": this.#endChunkSpan(chunk.object);
3010
3022
  }
3011
3023
  }
3012
3024
  /**
@@ -3016,8 +3028,8 @@ var ModelSpanTracker = class {
3016
3028
  #handleToolApprovalChunk(chunk) {
3017
3029
  if (chunk.type !== "tool-call-approval") return;
3018
3030
  const payload = chunk.payload;
3019
- this.#ensureStepAndInference();
3020
- if (this.#chunkParent()?.createEventSpan({
3031
+ if (payload.usage || this.#currentStepSpan) this.#ensureStepAndInference();
3032
+ if ((this.#chunkParent() ?? this.#modelSpan)?.createEventSpan({
3021
3033
  name: `chunk: 'tool-call-approval'`,
3022
3034
  type: _mastra_core_observability.SpanType.MODEL_CHUNK,
3023
3035
  attributes: {
@@ -3037,6 +3049,10 @@ var ModelSpanTracker = class {
3037
3049
  wrapStream(stream) {
3038
3050
  return stream.pipeThrough(new stream_web.TransformStream({ transform: (chunk, controller) => {
3039
3051
  if ((this.#inModelResponse || this.#deferStepClose) && MODEL_RESPONSE_CHUNK_TYPES.has(chunk.type)) this.#captureCompletionStartTime();
3052
+ if (chunk.type === "tool-call-suspended" || chunk.type === "tool-call-approval") {
3053
+ if (chunk.type === "tool-call-approval") this.#handleToolApprovalChunk(chunk);
3054
+ this.#endSuspendedStep(chunk);
3055
+ }
3040
3056
  controller.enqueue(chunk);
3041
3057
  switch (chunk.type) {
3042
3058
  case "text-start":
@@ -3084,13 +3100,11 @@ var ModelSpanTracker = class {
3084
3100
  case "tripwire":
3085
3101
  case "watch":
3086
3102
  case "tool-error":
3087
- case "tool-call-suspended":
3088
3103
  case "reasoning-signature":
3089
3104
  case "redacted-reasoning":
3090
3105
  case "step-output": break;
3091
- case "tool-call-approval":
3092
- this.#handleToolApprovalChunk(chunk);
3093
- break;
3106
+ case "tool-call-suspended":
3107
+ case "tool-call-approval": break;
3094
3108
  case "tool-output": break;
3095
3109
  case "tool-result": {
3096
3110
  const { toolCallId, toolName, isError, dynamic, providerExecuted, providerMetadata, result, args: _args } = chunk.payload || {};
@@ -3107,7 +3121,6 @@ var ModelSpanTracker = class {
3107
3121
  this.#createEventSpan(chunk.type, spanOutput, { metadata });
3108
3122
  break;
3109
3123
  }
3110
- default: break;
3111
3124
  }
3112
3125
  } }));
3113
3126
  }
@@ -3648,10 +3661,14 @@ var DefaultSpan = class extends BaseSpan {
3648
3661
  }
3649
3662
  this.traceId = getOrCreateTraceId(options);
3650
3663
  this.id = generateSpanId();
3651
- if (options.parentSpanId) if (isValidSpanId(options.parentSpanId)) this.parentSpanId = options.parentSpanId;
3652
- else console.error(`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring.`);
3653
- if (options.externalParentSpanId) if (isValidSpanId(options.externalParentSpanId)) this.externalParentSpanId = options.externalParentSpanId;
3654
- else console.error(`[Mastra Tracing] Invalid externalParentSpanId: must be 1-16 hexadecimal characters, got "${options.externalParentSpanId}". Ignoring.`);
3664
+ if (options.parentSpanId) {
3665
+ if (isValidSpanId(options.parentSpanId)) this.parentSpanId = options.parentSpanId;
3666
+ else console.error(`[Mastra Tracing] Invalid parentSpanId: must be 1-16 hexadecimal characters, got "${options.parentSpanId}". Ignoring.`);
3667
+ }
3668
+ if (options.externalParentSpanId) {
3669
+ if (isValidSpanId(options.externalParentSpanId)) this.externalParentSpanId = options.externalParentSpanId;
3670
+ else console.error(`[Mastra Tracing] Invalid externalParentSpanId: must be 1-16 hexadecimal characters, got "${options.externalParentSpanId}". Ignoring.`);
3671
+ }
3655
3672
  }
3656
3673
  end(options) {
3657
3674
  if (this.isEvent) return;
@@ -3773,8 +3790,10 @@ function isValidSpanId(spanId) {
3773
3790
  return /^[0-9a-f]{1,16}$/i.test(spanId);
3774
3791
  }
3775
3792
  function getOrCreateTraceId(options) {
3776
- if (options.traceId) if (isValidTraceId(options.traceId)) return options.traceId;
3777
- else console.error(`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`);
3793
+ if (options.traceId) {
3794
+ if (isValidTraceId(options.traceId)) return options.traceId;
3795
+ else console.error(`[Mastra Tracing] Invalid traceId: must be 1-32 hexadecimal characters, got "${options.traceId}". Generating new trace ID.`);
3796
+ }
3778
3797
  return generateTraceId();
3779
3798
  }
3780
3799
  //#endregion
@@ -4023,17 +4042,13 @@ var EventBuffer = class {
4023
4042
  switch (this.#storageStrategy) {
4024
4043
  case "realtime":
4025
4044
  case "event-sourced":
4026
- case "batch-with-updates":
4027
- this.pushCreate(event);
4028
- break;
4045
+ case "batch-with-updates": this.pushCreate(event);
4029
4046
  }
4030
4047
  break;
4031
4048
  case _mastra_core_observability.TracingEventType.SPAN_UPDATED:
4032
4049
  switch (this.#storageStrategy) {
4033
4050
  case "realtime":
4034
- case "batch-with-updates":
4035
- this.pushUpdate(event);
4036
- break;
4051
+ case "batch-with-updates": this.pushUpdate(event);
4037
4052
  }
4038
4053
  break;
4039
4054
  case _mastra_core_observability.TracingEventType.SPAN_ENDED:
@@ -4043,14 +4058,10 @@ var EventBuffer = class {
4043
4058
  case "batch-with-updates":
4044
4059
  this.pushUpdate(event);
4045
4060
  break;
4046
- default:
4047
- this.pushCreate(event);
4048
- break;
4061
+ default: this.pushCreate(event);
4049
4062
  }
4050
4063
  break;
4051
- default:
4052
- this.pushCreate(event);
4053
- break;
4064
+ default: this.pushCreate(event);
4054
4065
  }
4055
4066
  }
4056
4067
  /** Re-add failed create events to the buffer, returning events that exceed max retries. */
@@ -4425,17 +4436,13 @@ var DefaultExporter = class extends BaseExporter {
4425
4436
  case "score":
4426
4437
  createScoreEvents.push(createEvent);
4427
4438
  break;
4428
- default:
4429
- createSpanEvents.push(createEvent);
4430
- break;
4439
+ default: createSpanEvents.push(createEvent);
4431
4440
  }
4432
4441
  for (const updateEvent of updates) switch (updateEvent.type) {
4433
4442
  case _mastra_core_observability.TracingEventType.SPAN_UPDATED:
4434
4443
  updateSpanEvents.push(updateEvent);
4435
4444
  break;
4436
- case _mastra_core_observability.TracingEventType.SPAN_ENDED:
4437
- endSpanEvents.push(updateEvent);
4438
- break;
4445
+ case _mastra_core_observability.TracingEventType.SPAN_ENDED: endSpanEvents.push(updateEvent);
4439
4446
  }
4440
4447
  const flushResults = await Promise.all([
4441
4448
  this.flushCreates("feedback", createFeedbackEvents, (events) => this.#observabilityStorage.batchCreateFeedback({ feedbacks: events.map((f) => (0, _mastra_core_storage.buildFeedbackRecord)(f)) })),
@@ -4452,13 +4459,15 @@ var DefaultExporter = class extends BaseExporter {
4452
4459
  flushResults.push(await this.flushSpanUpdates(updateSpanEvents, deferredUpdates, false));
4453
4460
  flushResults.push(await this.flushSpanUpdates(endSpanEvents, deferredUpdates, true));
4454
4461
  let deferredDropCount = 0;
4455
- if (deferredUpdates.length > 0) if (this.#unsupportedSignals.has("tracing")) {
4456
- deferredDropCount = deferredUpdates.length;
4457
- this.emitDrop("tracing", "unsupported-storage", deferredDropCount);
4458
- deferredUpdates.length = 0;
4459
- } else {
4460
- deferredDropCount = this.#eventBuffer.reAddUpdates(deferredUpdates).length;
4461
- this.emitDrop("tracing", "retry-exhausted", deferredDropCount);
4462
+ if (deferredUpdates.length > 0) {
4463
+ if (this.#unsupportedSignals.has("tracing")) {
4464
+ deferredDropCount = deferredUpdates.length;
4465
+ this.emitDrop("tracing", "unsupported-storage", deferredDropCount);
4466
+ deferredUpdates.length = 0;
4467
+ } else {
4468
+ deferredDropCount = this.#eventBuffer.reAddUpdates(deferredUpdates).length;
4469
+ this.emitDrop("tracing", "retry-exhausted", deferredDropCount);
4470
+ }
4462
4471
  }
4463
4472
  const retryAttempt = flushResults.reduce((earliestAttempt, result) => {
4464
4473
  if (result.retryAttempt === void 0) return earliestAttempt;
@@ -4876,17 +4885,13 @@ var MastraStorageExporter = class extends BaseExporter {
4876
4885
  case "score":
4877
4886
  createScoreEvents.push(createEvent);
4878
4887
  break;
4879
- default:
4880
- createSpanEvents.push(createEvent);
4881
- break;
4888
+ default: createSpanEvents.push(createEvent);
4882
4889
  }
4883
4890
  for (const updateEvent of updates) switch (updateEvent.type) {
4884
4891
  case _mastra_core_observability.TracingEventType.SPAN_UPDATED:
4885
4892
  updateSpanEvents.push(updateEvent);
4886
4893
  break;
4887
- case _mastra_core_observability.TracingEventType.SPAN_ENDED:
4888
- endSpanEvents.push(updateEvent);
4889
- break;
4894
+ case _mastra_core_observability.TracingEventType.SPAN_ENDED: endSpanEvents.push(updateEvent);
4890
4895
  }
4891
4896
  const flushResults = await Promise.all([
4892
4897
  this.flushCreates("feedback", createFeedbackEvents, (events) => this.#observabilityStorage.batchCreateFeedback({ feedbacks: events.map((f) => (0, _mastra_core_storage.buildFeedbackRecord)(f)) })),
@@ -4903,13 +4908,15 @@ var MastraStorageExporter = class extends BaseExporter {
4903
4908
  flushResults.push(await this.flushSpanUpdates(updateSpanEvents, deferredUpdates, false));
4904
4909
  flushResults.push(await this.flushSpanUpdates(endSpanEvents, deferredUpdates, true));
4905
4910
  let deferredDropCount = 0;
4906
- if (deferredUpdates.length > 0) if (this.#unsupportedSignals.has("tracing")) {
4907
- deferredDropCount = deferredUpdates.length;
4908
- this.emitDrop("tracing", "unsupported-storage", deferredDropCount);
4909
- deferredUpdates.length = 0;
4910
- } else {
4911
- deferredDropCount = this.#eventBuffer.reAddUpdates(deferredUpdates).length;
4912
- this.emitDrop("tracing", "retry-exhausted", deferredDropCount);
4911
+ if (deferredUpdates.length > 0) {
4912
+ if (this.#unsupportedSignals.has("tracing")) {
4913
+ deferredDropCount = deferredUpdates.length;
4914
+ this.emitDrop("tracing", "unsupported-storage", deferredDropCount);
4915
+ deferredUpdates.length = 0;
4916
+ } else {
4917
+ deferredDropCount = this.#eventBuffer.reAddUpdates(deferredUpdates).length;
4918
+ this.emitDrop("tracing", "retry-exhausted", deferredDropCount);
4919
+ }
4913
4920
  }
4914
4921
  const retryAttempt = flushResults.reduce((earliestAttempt, result) => {
4915
4922
  if (result.retryAttempt === void 0) return earliestAttempt;
@@ -5429,10 +5436,13 @@ var BaseObservabilityInstance = class extends _mastra_core_base.MastraBase {
5429
5436
  const parts = key.split(".");
5430
5437
  const rootKey = parts[0];
5431
5438
  const value = requestContext.get(rootKey);
5432
- if (value !== void 0) if (parts.length > 1) {
5433
- const nestedValue = (0, _mastra_core_utils.getNestedValue)(value, parts.slice(1).join("."));
5434
- if (nestedValue !== void 0) (0, _mastra_core_utils.setNestedValue)(result, key, nestedValue);
5435
- } else (0, _mastra_core_utils.setNestedValue)(result, key, value);
5439
+ if (value !== void 0) {
5440
+ if (parts.length > 1) {
5441
+ const nestedPath = parts.slice(1).join(".");
5442
+ const nestedValue = (0, _mastra_core_utils.getNestedValue)(value, nestedPath);
5443
+ if (nestedValue !== void 0) (0, _mastra_core_utils.setNestedValue)(result, key, nestedValue);
5444
+ } else (0, _mastra_core_utils.setNestedValue)(result, key, value);
5445
+ }
5436
5446
  }
5437
5447
  return result;
5438
5448
  }
@@ -5980,7 +5990,7 @@ function formatBaggage(entries) {
5980
5990
  const DEFAULT_LIMITS = {
5981
5991
  maxSpans: 10,
5982
5992
  maxLogs: 10,
5983
- maxPayloadBytes: 1024 * 1024
5993
+ maxPayloadBytes: 1048576
5984
5994
  };
5985
5995
  var ClientObservabilityProxyImpl = class {
5986
5996
  #resolveInstance;
@@ -6915,36 +6925,38 @@ var TrackingExporter = class extends BaseExporter {
6915
6925
  method
6916
6926
  });
6917
6927
  const { exportedSpan } = await this._preExportTracingEvent(event);
6918
- if (!this.skipBuildRootTask && !traceData.hasRoot()) if (exportedSpan.isRootSpan) {
6919
- this.logger.debug(`${this.name}: Building root`, {
6920
- traceId: exportedSpan.traceId,
6921
- spanId: exportedSpan.id
6922
- });
6923
- const rootData = await this._buildRoot({
6924
- span: exportedSpan,
6925
- traceData
6926
- });
6927
- if (rootData) {
6928
- this.logger.debug(`${this.name}: Adding root`, {
6928
+ if (!this.skipBuildRootTask && !traceData.hasRoot()) {
6929
+ if (exportedSpan.isRootSpan) {
6930
+ this.logger.debug(`${this.name}: Building root`, {
6931
+ traceId: exportedSpan.traceId,
6932
+ spanId: exportedSpan.id
6933
+ });
6934
+ const rootData = await this._buildRoot({
6935
+ span: exportedSpan,
6936
+ traceData
6937
+ });
6938
+ if (rootData) {
6939
+ this.logger.debug(`${this.name}: Adding root`, {
6940
+ traceId: exportedSpan.traceId,
6941
+ spanId: exportedSpan.id
6942
+ });
6943
+ traceData.addRoot({
6944
+ rootId: exportedSpan.id,
6945
+ rootData
6946
+ });
6947
+ this.#scheduleProcessWaitingForRoot(traceId);
6948
+ }
6949
+ } else {
6950
+ this.logger.debug(`${this.name}: Root does not exist, adding span to waiting queue.`, {
6929
6951
  traceId: exportedSpan.traceId,
6930
6952
  spanId: exportedSpan.id
6931
6953
  });
6932
- traceData.addRoot({
6933
- rootId: exportedSpan.id,
6934
- rootData
6954
+ traceData.addToWaitingQueue({
6955
+ event,
6956
+ waitingFor: "root"
6935
6957
  });
6936
- this.#scheduleProcessWaitingForRoot(traceId);
6958
+ return;
6937
6959
  }
6938
- } else {
6939
- this.logger.debug(`${this.name}: Root does not exist, adding span to waiting queue.`, {
6940
- traceId: exportedSpan.traceId,
6941
- spanId: exportedSpan.id
6942
- });
6943
- traceData.addToWaitingQueue({
6944
- event,
6945
- waitingFor: "root"
6946
- });
6947
- return;
6948
6960
  }
6949
6961
  if (exportedSpan.metadata && this.name in exportedSpan.metadata) {
6950
6962
  const metadata = exportedSpan.metadata[this.name];
@@ -7071,7 +7083,6 @@ var TrackingExporter = class extends BaseExporter {
7071
7083
  traceData
7072
7084
  });
7073
7085
  if (traceData.activeSpanCount() === 0) this.#scheduleCleanup(traceId);
7074
- break;
7075
7086
  }
7076
7087
  } catch (error) {
7077
7088
  this.logger.error(`${this.name}: exporter error`, {
@@ -7237,7 +7248,7 @@ function chainFormatters(formatters) {
7237
7248
  //#region src/exporters/auth-failure-cooldown.ts
7238
7249
  const AUTH_FAILURE_STATUSES = /* @__PURE__ */ new Set([401, 403]);
7239
7250
  const AUTH_COOLDOWN_BASE_MS = 6e4;
7240
- const AUTH_COOLDOWN_MAX_MS = 15 * 6e4;
7251
+ const AUTH_COOLDOWN_MAX_MS = 9e5;
7241
7252
  const AUTH_COOLDOWN_JITTER_RATIO = .1;
7242
7253
  var AuthFailureError = class extends Error {
7243
7254
  status;
@@ -7666,8 +7677,9 @@ var CloudExporter = class extends BaseExporter {
7666
7677
  succeeded: false,
7667
7678
  authFailureStatus: error.status
7668
7679
  };
7680
+ const errorId = `CLOUD_EXPORTER_FAILED_TO_BATCH_UPLOAD_${signal.toUpperCase()}`;
7669
7681
  const mastraError = new _mastra_core_error.MastraError({
7670
- id: `CLOUD_EXPORTER_FAILED_TO_BATCH_UPLOAD_${signal.toUpperCase()}`,
7682
+ id: errorId,
7671
7683
  domain: _mastra_core_error.ErrorDomain.MASTRA_OBSERVABILITY,
7672
7684
  category: _mastra_core_error.ErrorCategory.USER,
7673
7685
  details: {
@@ -8256,8 +8268,9 @@ var MastraPlatformExporter = class extends BaseExporter {
8256
8268
  succeeded: false,
8257
8269
  authFailureStatus: error.status
8258
8270
  };
8271
+ const errorId = `MASTRA_PLATFORM_EXPORTER_FAILED_TO_BATCH_UPLOAD_${signal.toUpperCase()}`;
8259
8272
  const mastraError = new _mastra_core_error.MastraError({
8260
- id: `MASTRA_PLATFORM_EXPORTER_FAILED_TO_BATCH_UPLOAD_${signal.toUpperCase()}`,
8273
+ id: errorId,
8261
8274
  domain: _mastra_core_error.ErrorDomain.MASTRA_OBSERVABILITY,
8262
8275
  category: _mastra_core_error.ErrorCategory.USER,
8263
8276
  details: {
@@ -9121,16 +9134,18 @@ var TestExporter = class extends BaseExporter {
9121
9134
  for (let i = 0; i < maxLen; i++) {
9122
9135
  const actualLine = actual[i];
9123
9136
  const expectedLine = expected[i];
9124
- if (actualLine !== expectedLine) if (actualLine === void 0) {
9125
- diffs.push(`Line ${i + 1}: Missing in actual`);
9126
- diffs.push(` Expected: ${expectedLine}`);
9127
- } else if (expectedLine === void 0) {
9128
- diffs.push(`Line ${i + 1}: Extra in actual`);
9129
- diffs.push(` Actual: ${actualLine}`);
9130
- } else {
9131
- diffs.push(`Line ${i + 1}:`);
9132
- diffs.push(` Expected: ${expectedLine}`);
9133
- diffs.push(` Actual: ${actualLine}`);
9137
+ if (actualLine !== expectedLine) {
9138
+ if (actualLine === void 0) {
9139
+ diffs.push(`Line ${i + 1}: Missing in actual`);
9140
+ diffs.push(` Expected: ${expectedLine}`);
9141
+ } else if (expectedLine === void 0) {
9142
+ diffs.push(`Line ${i + 1}: Extra in actual`);
9143
+ diffs.push(` Actual: ${actualLine}`);
9144
+ } else {
9145
+ diffs.push(`Line ${i + 1}:`);
9146
+ diffs.push(` Expected: ${expectedLine}`);
9147
+ diffs.push(` Actual: ${actualLine}`);
9148
+ }
9134
9149
  }
9135
9150
  }
9136
9151
  return diffs;
@@ -9139,15 +9154,15 @@ var TestExporter = class extends BaseExporter {
9139
9154
  * Deep compare two values, supporting special markers like __or__ and __any__.
9140
9155
  * Collects all mismatches into the provided array.
9141
9156
  */
9142
- #deepCompareWithMarkers(actual, expected, path$2, mismatches) {
9157
+ #deepCompareWithMarkers(actual, expected, path, mismatches) {
9143
9158
  if (this.#isOrMarker(expected)) {
9144
9159
  const allowedValues = expected.__or__;
9145
9160
  if (!allowedValues.some((allowed) => {
9146
9161
  const tempMismatches = [];
9147
- this.#deepCompareWithMarkers(actual, allowed, path$2, tempMismatches);
9162
+ this.#deepCompareWithMarkers(actual, allowed, path, tempMismatches);
9148
9163
  return tempMismatches.length === 0;
9149
9164
  })) mismatches.push({
9150
- path: path$2,
9165
+ path,
9151
9166
  expected: { __or__: allowedValues },
9152
9167
  actual
9153
9168
  });
@@ -9157,7 +9172,7 @@ var TestExporter = class extends BaseExporter {
9157
9172
  const typeConstraint = expected.__any__;
9158
9173
  if (actual === null || actual === void 0) {
9159
9174
  mismatches.push({
9160
- path: path$2,
9175
+ path,
9161
9176
  expected: { __any__: typeConstraint },
9162
9177
  actual
9163
9178
  });
@@ -9166,7 +9181,7 @@ var TestExporter = class extends BaseExporter {
9166
9181
  if (typeConstraint === true) return;
9167
9182
  const actualType = Array.isArray(actual) ? "array" : typeof actual;
9168
9183
  if (actualType !== typeConstraint) mismatches.push({
9169
- path: path$2,
9184
+ path,
9170
9185
  expected: { __any__: typeConstraint },
9171
9186
  actual: `(${actualType}) ${JSON.stringify(actual).slice(0, 50)}...`
9172
9187
  });
@@ -9175,7 +9190,7 @@ var TestExporter = class extends BaseExporter {
9175
9190
  if (Array.isArray(expected)) {
9176
9191
  if (!Array.isArray(actual)) {
9177
9192
  mismatches.push({
9178
- path: path$2,
9193
+ path,
9179
9194
  expected,
9180
9195
  actual
9181
9196
  });
@@ -9183,19 +9198,19 @@ var TestExporter = class extends BaseExporter {
9183
9198
  }
9184
9199
  if (actual.length !== expected.length) {
9185
9200
  mismatches.push({
9186
- path: `${path$2}.length`,
9201
+ path: `${path}.length`,
9187
9202
  expected: expected.length,
9188
9203
  actual: actual.length
9189
9204
  });
9190
9205
  return;
9191
9206
  }
9192
- for (let i = 0; i < expected.length; i++) this.#deepCompareWithMarkers(actual[i], expected[i], `${path$2}[${i}]`, mismatches);
9207
+ for (let i = 0; i < expected.length; i++) this.#deepCompareWithMarkers(actual[i], expected[i], `${path}[${i}]`, mismatches);
9193
9208
  return;
9194
9209
  }
9195
9210
  if (expected !== null && typeof expected === "object") {
9196
9211
  if (actual === null || typeof actual !== "object" || Array.isArray(actual)) {
9197
9212
  mismatches.push({
9198
- path: path$2,
9213
+ path,
9199
9214
  expected,
9200
9215
  actual
9201
9216
  });
@@ -9207,19 +9222,19 @@ var TestExporter = class extends BaseExporter {
9207
9222
  if (this.#isMetadataKey(key)) continue;
9208
9223
  if (!(key in actualObj)) {
9209
9224
  if (expectedObj[key] !== void 0) mismatches.push({
9210
- path: `${path$2}.${key}`,
9225
+ path: `${path}.${key}`,
9211
9226
  expected: expectedObj[key],
9212
9227
  actual: void 0
9213
9228
  });
9214
9229
  continue;
9215
9230
  }
9216
- this.#deepCompareWithMarkers(actualObj[key], expectedObj[key], `${path$2}.${key}`, mismatches);
9231
+ this.#deepCompareWithMarkers(actualObj[key], expectedObj[key], `${path}.${key}`, mismatches);
9217
9232
  }
9218
9233
  for (const key of Object.keys(actualObj)) {
9219
9234
  if (this.#isMetadataKey(key)) continue;
9220
9235
  if (!(key in expectedObj)) {
9221
9236
  if (actualObj[key] !== void 0) mismatches.push({
9222
- path: `${path$2}.${key}`,
9237
+ path: `${path}.${key}`,
9223
9238
  expected: void 0,
9224
9239
  actual: actualObj[key]
9225
9240
  });
@@ -9228,7 +9243,7 @@ var TestExporter = class extends BaseExporter {
9228
9243
  return;
9229
9244
  }
9230
9245
  if (actual !== expected) mismatches.push({
9231
- path: path$2,
9246
+ path,
9232
9247
  expected,
9233
9248
  actual
9234
9249
  });
@@ -9893,9 +9908,10 @@ var SensitiveDataFilter = class {
9893
9908
  const filtered = {};
9894
9909
  for (const key of Object.keys(obj)) {
9895
9910
  const normKey = this.normalizeKey(key);
9896
- if (this.isSensitive(normKey)) if (obj[key] && typeof obj[key] === "object") filtered[key] = this.deepFilter(obj[key], seen, indexedState);
9897
- else filtered[key] = this.redactValue(obj[key], normKey, indexedState);
9898
- else filtered[key] = this.deepFilter(obj[key], seen, indexedState);
9911
+ if (this.isSensitive(normKey)) {
9912
+ if (obj[key] && typeof obj[key] === "object") filtered[key] = this.deepFilter(obj[key], seen, indexedState);
9913
+ else filtered[key] = this.redactValue(obj[key], normKey, indexedState);
9914
+ } else filtered[key] = this.deepFilter(obj[key], seen, indexedState);
9899
9915
  }
9900
9916
  return filtered;
9901
9917
  }