@use-tusk/drift-node-sdk 0.1.16 → 0.1.18

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.js CHANGED
@@ -4978,31 +4978,31 @@ var require_SamplingResult = /* @__PURE__ */ __commonJS({ "node_modules/@opentel
4978
4978
  var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/span_kind.js": ((exports) => {
4979
4979
  Object.defineProperty(exports, "__esModule", { value: true });
4980
4980
  exports.SpanKind = void 0;
4981
- (function(SpanKind$24) {
4981
+ (function(SpanKind$25) {
4982
4982
  /** Default value. Indicates that the span is used internally. */
4983
- SpanKind$24[SpanKind$24["INTERNAL"] = 0] = "INTERNAL";
4983
+ SpanKind$25[SpanKind$25["INTERNAL"] = 0] = "INTERNAL";
4984
4984
  /**
4985
4985
  * Indicates that the span covers server-side handling of an RPC or other
4986
4986
  * remote request.
4987
4987
  */
4988
- SpanKind$24[SpanKind$24["SERVER"] = 1] = "SERVER";
4988
+ SpanKind$25[SpanKind$25["SERVER"] = 1] = "SERVER";
4989
4989
  /**
4990
4990
  * Indicates that the span covers the client-side wrapper around an RPC or
4991
4991
  * other remote request.
4992
4992
  */
4993
- SpanKind$24[SpanKind$24["CLIENT"] = 2] = "CLIENT";
4993
+ SpanKind$25[SpanKind$25["CLIENT"] = 2] = "CLIENT";
4994
4994
  /**
4995
4995
  * Indicates that the span describes producer sending a message to a
4996
4996
  * broker. Unlike client and server, there is no direct critical path latency
4997
4997
  * relationship between producer and consumer spans.
4998
4998
  */
4999
- SpanKind$24[SpanKind$24["PRODUCER"] = 3] = "PRODUCER";
4999
+ SpanKind$25[SpanKind$25["PRODUCER"] = 3] = "PRODUCER";
5000
5000
  /**
5001
5001
  * Indicates that the span describes consumer receiving a message from a
5002
5002
  * broker. Unlike client and server, there is no direct critical path latency
5003
5003
  * relationship between producer and consumer spans.
5004
5004
  */
5005
- SpanKind$24[SpanKind$24["CONSUMER"] = 4] = "CONSUMER";
5005
+ SpanKind$25[SpanKind$25["CONSUMER"] = 4] = "CONSUMER";
5006
5006
  })(exports.SpanKind || (exports.SpanKind = {}));
5007
5007
  }) });
5008
5008
 
@@ -5011,20 +5011,20 @@ var require_span_kind = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetr
5011
5011
  var require_status = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/api/build/src/trace/status.js": ((exports) => {
5012
5012
  Object.defineProperty(exports, "__esModule", { value: true });
5013
5013
  exports.SpanStatusCode = void 0;
5014
- (function(SpanStatusCode$13) {
5014
+ (function(SpanStatusCode$14) {
5015
5015
  /**
5016
5016
  * The default status.
5017
5017
  */
5018
- SpanStatusCode$13[SpanStatusCode$13["UNSET"] = 0] = "UNSET";
5018
+ SpanStatusCode$14[SpanStatusCode$14["UNSET"] = 0] = "UNSET";
5019
5019
  /**
5020
5020
  * The operation has been validated by an Application developer or
5021
5021
  * Operator to have completed successfully.
5022
5022
  */
5023
- SpanStatusCode$13[SpanStatusCode$13["OK"] = 1] = "OK";
5023
+ SpanStatusCode$14[SpanStatusCode$14["OK"] = 1] = "OK";
5024
5024
  /**
5025
5025
  * The operation contains an error.
5026
5026
  */
5027
- SpanStatusCode$13[SpanStatusCode$13["ERROR"] = 2] = "ERROR";
5027
+ SpanStatusCode$14[SpanStatusCode$14["ERROR"] = 2] = "ERROR";
5028
5028
  })(exports.SpanStatusCode || (exports.SpanStatusCode = {}));
5029
5029
  }) });
5030
5030
 
@@ -6198,7 +6198,7 @@ var JsonSchema$Type = class extends import_commonjs$7.MessageType {
6198
6198
  const JsonSchema = new JsonSchema$Type();
6199
6199
 
6200
6200
  //#endregion
6201
- //#region node_modules/@use-tusk/drift-schemas/dist/span-BZ89ct3l.js
6201
+ //#region node_modules/@use-tusk/drift-schemas/dist/span-CsBrzhI_.js
6202
6202
  var import_commonjs$6 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
6203
6203
  /**
6204
6204
  * Package type classification enum
@@ -6284,7 +6284,7 @@ let PackageType = /* @__PURE__ */ function(PackageType$1) {
6284
6284
  *
6285
6285
  * @generated from protobuf enum tusk.drift.core.v1.SpanKind
6286
6286
  */
6287
- let SpanKind = /* @__PURE__ */ function(SpanKind$1$1) {
6287
+ let SpanKind$1 = /* @__PURE__ */ function(SpanKind$1$1) {
6288
6288
  /**
6289
6289
  * @generated from protobuf enum value: SPAN_KIND_UNSPECIFIED = 0;
6290
6290
  */
@@ -6454,7 +6454,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6454
6454
  kind: "enum",
6455
6455
  T: () => [
6456
6456
  "tusk.drift.core.v1.SpanKind",
6457
- SpanKind,
6457
+ SpanKind$1,
6458
6458
  "SPAN_KIND_"
6459
6459
  ]
6460
6460
  },
@@ -6493,6 +6493,13 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6493
6493
  name: "metadata",
6494
6494
  kind: "message",
6495
6495
  T: () => Struct
6496
+ },
6497
+ {
6498
+ no: 24,
6499
+ name: "environment",
6500
+ kind: "scalar",
6501
+ opt: true,
6502
+ T: 9
6496
6503
  }
6497
6504
  ]);
6498
6505
  }
@@ -6590,6 +6597,9 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6590
6597
  case 23:
6591
6598
  message.metadata = Struct.internalBinaryRead(reader, reader.uint32(), options, message.metadata);
6592
6599
  break;
6600
+ case 24:
6601
+ message.environment = reader.string();
6602
+ break;
6593
6603
  default:
6594
6604
  let u = options.readUnknownField;
6595
6605
  if (u === "throw") throw new globalThis.Error(`Unknown field ${fieldNo} (wire type ${wireType}) for ${this.typeName}`);
@@ -6623,6 +6633,7 @@ var Span$Type = class extends import_commonjs$6.MessageType {
6623
6633
  if (message.duration) Duration.internalBinaryWrite(message.duration, writer.tag(21, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
6624
6634
  if (message.isRootSpan !== false) writer.tag(22, import_commonjs$6.WireType.Varint).bool(message.isRootSpan);
6625
6635
  if (message.metadata) Struct.internalBinaryWrite(message.metadata, writer.tag(23, import_commonjs$6.WireType.LengthDelimited).fork(), options).join();
6636
+ if (message.environment !== void 0) writer.tag(24, import_commonjs$6.WireType.LengthDelimited).string(message.environment);
6626
6637
  let u = options.writeUnknownFields;
6627
6638
  if (u !== false) (u == true ? import_commonjs$6.UnknownFieldHandler.onWrite : u)(this.typeName, message, writer);
6628
6639
  return writer;
@@ -6986,12 +6997,12 @@ const Trace = new Trace$Type();
6986
6997
  const toStruct = (obj) => obj ? objectToProtobufStruct(obj) : void 0;
6987
6998
  const mapOtToPb = (k) => {
6988
6999
  switch (k) {
6989
- case import_src$34.SpanKind.INTERNAL: return SpanKind.INTERNAL;
6990
- case import_src$34.SpanKind.SERVER: return SpanKind.SERVER;
6991
- case import_src$34.SpanKind.CLIENT: return SpanKind.CLIENT;
6992
- case import_src$34.SpanKind.PRODUCER: return SpanKind.PRODUCER;
6993
- case import_src$34.SpanKind.CONSUMER: return SpanKind.CONSUMER;
6994
- default: return SpanKind.UNSPECIFIED;
7000
+ case import_src$34.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
7001
+ case import_src$34.SpanKind.SERVER: return SpanKind$1.SERVER;
7002
+ case import_src$34.SpanKind.CLIENT: return SpanKind$1.CLIENT;
7003
+ case import_src$34.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
7004
+ case import_src$34.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
7005
+ default: return SpanKind$1.UNSPECIFIED;
6995
7006
  }
6996
7007
  };
6997
7008
  /**
@@ -7575,7 +7586,7 @@ var SpanUtils = class SpanUtils {
7575
7586
  return originalFunctionCall();
7576
7587
  }
7577
7588
  }
7578
- const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
7589
+ const { name, kind, packageName, instrumentationName, packageType, submodule, inputValue, outputValue, inputSchemaMerges, isPreAppStart, metadata, stopRecordingChildSpans } = options;
7579
7590
  let spanInfo = null;
7580
7591
  try {
7581
7592
  spanInfo = SpanUtils.createSpan({
@@ -7589,6 +7600,7 @@ var SpanUtils = class SpanUtils {
7589
7600
  [TdSpanAttributes.INSTRUMENTATION_NAME]: instrumentationName,
7590
7601
  [TdSpanAttributes.PACKAGE_TYPE]: packageType,
7591
7602
  [TdSpanAttributes.INPUT_VALUE]: createSpanInputValue(inputValue),
7603
+ ...outputValue && { [TdSpanAttributes.OUTPUT_VALUE]: JSON.stringify(outputValue) },
7592
7604
  [TdSpanAttributes.IS_PRE_APP_START]: isPreAppStart,
7593
7605
  ...inputSchemaMerges && { [TdSpanAttributes.INPUT_SCHEMA_MERGES]: JSON.stringify(inputSchemaMerges) },
7594
7606
  ...metadata && { [TdSpanAttributes.METADATA]: JSON.stringify(metadata) }
@@ -7853,7 +7865,10 @@ function getDecodedType(contentType) {
7853
7865
  logger.debug(`Invalid Content-Type header: ${contentType}`);
7854
7866
  return;
7855
7867
  }
7856
- return CONTENT_TYPE_MAPPING[contentTypeString.toLowerCase().split(";")[0].trim()];
7868
+ const mainType = contentTypeString.toLowerCase().split(";")[0].trim();
7869
+ const decodedType = CONTENT_TYPE_MAPPING[mainType];
7870
+ if (decodedType !== void 0) return decodedType;
7871
+ if (mainType.includes("json")) return DecodedType.JSON;
7857
7872
  }
7858
7873
  const ACCEPTABLE_CONTENT_TYPES = new Set([DecodedType.JSON, DecodedType.PLAIN_TEXT]);
7859
7874
 
@@ -7952,30 +7967,6 @@ var TdHttpMockSocket = class extends EventEmitter {
7952
7967
  }
7953
7968
  };
7954
7969
 
7955
- //#endregion
7956
- //#region src/instrumentation/core/trackers/EnvVarTracker.ts
7957
- var EnvVarTracker = class {
7958
- static setEnvVar({ traceId, key, value }) {
7959
- this.envVars.set(traceId, {
7960
- ...this.envVars.get(traceId) || {},
7961
- [key]: value
7962
- });
7963
- }
7964
- static setEnvVars(traceId, envVars) {
7965
- this.envVars.set(traceId, envVars);
7966
- }
7967
- static getEnvVar(traceId, key) {
7968
- return this.envVars.get(traceId)?.[key];
7969
- }
7970
- static getEnvVars(traceId) {
7971
- return this.envVars.get(traceId);
7972
- }
7973
- static clearEnvVars(traceId) {
7974
- this.envVars.delete(traceId);
7975
- }
7976
- };
7977
- EnvVarTracker.envVars = /* @__PURE__ */ new Map();
7978
-
7979
7970
  //#endregion
7980
7971
  //#region src/instrumentation/core/trackers/DateTracker.ts
7981
7972
  /**
@@ -8198,10 +8189,17 @@ var JsonSchemaHelper = class JsonSchemaHelper {
8198
8189
  static decodeDataWithMerges(data, schemaMerges) {
8199
8190
  if (!schemaMerges) return data;
8200
8191
  const decodedData = { ...data };
8201
- for (const [key, schema] of Object.entries(schemaMerges)) if (schema.encoding && schema.decodedType && data[key] !== void 0) try {
8192
+ for (const [key, schema] of Object.entries(schemaMerges)) if (schema.encoding && data[key] !== void 0) try {
8202
8193
  let decodedValue = data[key];
8203
- if (schema.encoding === EncodingType.BASE64 && typeof decodedValue === "string") decodedValue = Buffer.from(decodedValue, "base64").toString("utf8");
8204
- if (schema.decodedType === DecodedType.JSON && typeof decodedValue === "string") decodedValue = JSON.parse(decodedValue);
8194
+ if (typeof decodedValue === "string") {
8195
+ if (schema.encoding === EncodingType.BASE64) decodedValue = Buffer.from(decodedValue, "base64").toString("utf8");
8196
+ if (schema.decodedType === DecodedType.JSON) decodedValue = JSON.parse(decodedValue);
8197
+ else if (!schema.decodedType) try {
8198
+ decodedValue = JSON.parse(decodedValue);
8199
+ } catch {
8200
+ logger.debug(`[JsonSchemaHelper] Failed to parse JSON for key: ${key}, no decodedType specified`);
8201
+ }
8202
+ }
8205
8203
  decodedData[key] = decodedValue;
8206
8204
  } catch (error) {
8207
8205
  logger.debug(`[JsonSchemaHelper] Failed to decode ${key}:`, error);
@@ -8269,6 +8267,7 @@ function convertMockRequestDataToCleanSpanData(mockRequestData, tuskDrift, input
8269
8267
  return {
8270
8268
  ...mockRequestData,
8271
8269
  parentSpanId: "",
8270
+ environment: tuskDrift.getEnvironment(),
8272
8271
  inputValueHash,
8273
8272
  inputSchema,
8274
8273
  inputSchemaHash,
@@ -8665,13 +8664,6 @@ var HttpReplayHooks = class {
8665
8664
  return traceIdHeader ? String(traceIdHeader) : null;
8666
8665
  }
8667
8666
  /**
8668
- * Check if we should fetch env vars from CLI
8669
- */
8670
- extractShouldFetchEnvVars(req) {
8671
- const fetchHeader = req.headers["x-td-fetch-env-vars"] || req.headers["X-TD-FETCH-ENV-VARS"];
8672
- return fetchHeader === "true" || fetchHeader === true;
8673
- }
8674
- /**
8675
8667
  * Handle outbound HTTP requests in replay mode
8676
8668
  * Uses TdMockClientRequest for simplified mocking approach
8677
8669
  */
@@ -9960,7 +9952,7 @@ var require_commonjs$1 = /* @__PURE__ */ __commonJS({ "node_modules/@protobuf-ts
9960
9952
  }) });
9961
9953
 
9962
9954
  //#endregion
9963
- //#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-XwF6hpEK.js
9955
+ //#region node_modules/@use-tusk/drift-schemas/dist/span_export_service-CmkFvTqD.js
9964
9956
  var import_commonjs$4 = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
9965
9957
  var import_commonjs$5 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
9966
9958
  var ExportSpansRequest$Type = class extends import_commonjs$5.MessageType {
@@ -10650,13 +10642,6 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
10650
10642
  return originalHandler.call(this);
10651
10643
  }
10652
10644
  logger.debug(`[HttpInstrumentation] Setting replay trace id`, replayTraceId);
10653
- if (this.replayHooks.extractShouldFetchEnvVars(req)) try {
10654
- const envVars = this.tuskDrift.requestEnvVarsSync(replayTraceId);
10655
- EnvVarTracker.setEnvVars(replayTraceId, envVars);
10656
- logger.debug(`[HttpInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
10657
- } catch (error) {
10658
- logger.error(`[HttpInstrumentation] Failed to fetch env vars from CLI:`, error);
10659
- }
10660
10645
  const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
10661
10646
  if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
10662
10647
  return import_src$28.context.with(ctxWithReplayTraceId, () => {
@@ -10799,10 +10784,8 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
10799
10784
  },
10800
10785
  headers: { matchImportance: 0 }
10801
10786
  },
10802
- metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) },
10803
10787
  ...spanData.transformMetadata && { transformMetadata: spanData.transformMetadata }
10804
10788
  });
10805
- EnvVarTracker.clearEnvVars(spanInfo.traceId);
10806
10789
  const status = statusCode >= 400 ? {
10807
10790
  code: import_src$28.SpanStatusCode.ERROR,
10808
10791
  message: `HTTP ${statusCode}`
@@ -10848,6 +10831,7 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
10848
10831
  instrumentationName: "HttpInstrumentation",
10849
10832
  submoduleName: completeInputValue.method || inputValue.method,
10850
10833
  inputValue: completeInputValue,
10834
+ environment: self.tuskDrift.getEnvironment(),
10851
10835
  outputValue,
10852
10836
  inputSchema,
10853
10837
  outputSchema,
@@ -11368,96 +11352,6 @@ var HttpInstrumentation = class extends TdInstrumentationBase {
11368
11352
  }
11369
11353
  };
11370
11354
 
11371
- //#endregion
11372
- //#region src/instrumentation/libraries/env/Instrumentation.ts
11373
- /**
11374
- * Environment variable instrumentation that records and replays process.env access.
11375
- * In record mode, captures environment variable values.
11376
- * In replay mode, returns previously recorded values for deterministic behavior.
11377
- */
11378
- var EnvInstrumentation = class extends TdInstrumentationBase {
11379
- constructor(config = {}) {
11380
- super("env", config);
11381
- this.isInPatchedCall = false;
11382
- this.mode = config.mode || TuskDriftMode.DISABLED;
11383
- }
11384
- init() {
11385
- this.patchProcessEnv();
11386
- return [];
11387
- }
11388
- patchProcessEnv() {
11389
- if (this.mode === TuskDriftMode.DISABLED || !this._config.enabled) return;
11390
- this.originalProcessEnv = process.env;
11391
- const envProxy = new Proxy(this.originalProcessEnv, {
11392
- get: (target, property, receiver) => {
11393
- return this._handleEnvAccess(target, property);
11394
- },
11395
- set: (target, property, value, receiver) => {
11396
- target[property] = value;
11397
- return true;
11398
- },
11399
- deleteProperty: (target, property) => {
11400
- delete target[property];
11401
- return true;
11402
- },
11403
- ownKeys: (target) => {
11404
- return Reflect.ownKeys(target);
11405
- },
11406
- getOwnPropertyDescriptor: (target, property) => {
11407
- return Reflect.getOwnPropertyDescriptor(target, property);
11408
- },
11409
- has: (target, property) => {
11410
- return Reflect.has(target, property);
11411
- }
11412
- });
11413
- process.env = envProxy;
11414
- }
11415
- _handleEnvAccess(target, key) {
11416
- if (this.isInPatchedCall) return target[key];
11417
- if (!TuskDriftCore.getInstance().isAppReady()) return target[key];
11418
- this.isInPatchedCall = true;
11419
- try {
11420
- return this._handleEnvAccessInMode(target, key);
11421
- } finally {
11422
- this.isInPatchedCall = false;
11423
- }
11424
- }
11425
- _handleEnvAccessInMode(target, key) {
11426
- let currentSpanInfo = null;
11427
- try {
11428
- currentSpanInfo = SpanUtils.getCurrentSpanInfo();
11429
- } catch (error) {
11430
- logger.error(`EnvInstrumentation error getting current span info:`, error);
11431
- }
11432
- if (!currentSpanInfo) return target[key];
11433
- if (this.mode === TuskDriftMode.REPLAY) return this._handleReplayMode(target, key);
11434
- else if (this.mode === TuskDriftMode.RECORD) return this._handleRecordMode(currentSpanInfo, target, key);
11435
- else return target[key];
11436
- }
11437
- _handleReplayMode(target, key) {
11438
- const replayTraceId = SpanUtils.getCurrentReplayTraceId();
11439
- if (!replayTraceId) return target[key];
11440
- const envVar = EnvVarTracker.getEnvVar(replayTraceId, key);
11441
- if (envVar) {
11442
- logger.debug(`Returning env var ${key} for trace ${replayTraceId}: ${envVar}`);
11443
- return envVar;
11444
- }
11445
- return target[key];
11446
- }
11447
- _handleRecordMode(spanInfo, target, key) {
11448
- try {
11449
- EnvVarTracker.setEnvVar({
11450
- traceId: spanInfo.traceId,
11451
- key,
11452
- value: target[key] || void 0
11453
- });
11454
- } catch (error) {
11455
- logger.error(`EnvInstrumentation error storing env var:`, error);
11456
- }
11457
- return target[key];
11458
- }
11459
- };
11460
-
11461
11355
  //#endregion
11462
11356
  //#region src/instrumentation/libraries/date/Instrumentation.ts
11463
11357
  var import_src$27 = /* @__PURE__ */ __toESM(require_src$7(), 1);
@@ -19542,13 +19436,6 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
19542
19436
  return originalHandleRequest.call(this, req, res, parsedUrl);
19543
19437
  }
19544
19438
  logger.debug(`[NextjsInstrumentation] Setting replay trace id`, replayTraceId);
19545
- if (self.replayHooks.extractShouldFetchEnvVars(req)) try {
19546
- const envVars = self.tuskDrift.requestEnvVarsSync(replayTraceId);
19547
- EnvVarTracker.setEnvVars(replayTraceId, envVars);
19548
- logger.debug(`[NextjsInstrumentation] Fetched env vars from CLI for trace ${replayTraceId}`);
19549
- } catch (error) {
19550
- logger.error(`[NextjsInstrumentation] Failed to fetch env vars from CLI:`, error);
19551
- }
19552
19439
  const ctxWithReplayTraceId = SpanUtils.setCurrentReplayTraceId(replayTraceId);
19553
19440
  if (!ctxWithReplayTraceId) throw new Error("Error setting current replay trace id");
19554
19441
  return import_src$11.context.with(ctxWithReplayTraceId, () => {
@@ -19703,10 +19590,8 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
19703
19590
  decodedType: getDecodedType(outputValue.headers?.["content-type"] || "")
19704
19591
  },
19705
19592
  headers: { matchImportance: 0 }
19706
- },
19707
- metadata: { ENV_VARS: EnvVarTracker.getEnvVars(spanInfo.traceId) }
19593
+ }
19708
19594
  });
19709
- EnvVarTracker.clearEnvVars(spanInfo.traceId);
19710
19595
  const status = (capturedStatusCode || 200) >= 400 ? {
19711
19596
  code: import_src$11.SpanStatusCode.ERROR,
19712
19597
  message: `HTTP ${capturedStatusCode}`
@@ -19744,6 +19629,7 @@ var NextjsInstrumentation = class extends TdInstrumentationBase {
19744
19629
  instrumentationName: self.INSTRUMENTATION_NAME,
19745
19630
  submoduleName: completeInputValue.method,
19746
19631
  inputValue: completeInputValue,
19632
+ environment: self.tuskDrift.getEnvironment(),
19747
19633
  outputValue,
19748
19634
  inputSchema,
19749
19635
  outputSchema,
@@ -24233,7 +24119,7 @@ var SpanTransformer = class SpanTransformer {
24233
24119
  * Return type is derived from protobuf schema but uses clean JSON.
24234
24120
  * We use JSON because serialized protobuf is extremely verbose and not readable.
24235
24121
  */
24236
- static transformSpanToCleanJSON(span) {
24122
+ static transformSpanToCleanJSON(span, environment) {
24237
24123
  const isRootSpan = !span.parentSpanId || span.kind === import_src$9.SpanKind.SERVER;
24238
24124
  const attributes = span.attributes;
24239
24125
  const packageName = SpanTransformer.extractPackageName(attributes);
@@ -24277,6 +24163,7 @@ var SpanTransformer = class SpanTransformer {
24277
24163
  instrumentationName,
24278
24164
  submoduleName: submoduleName || "",
24279
24165
  packageType: attributes[TdSpanAttributes.PACKAGE_TYPE] || void 0,
24166
+ environment,
24280
24167
  inputValue: inputData,
24281
24168
  outputValue: outputData,
24282
24169
  inputSchema,
@@ -24740,7 +24627,7 @@ var ApiSpanAdapter = class {
24740
24627
  const protoSpans = spans.map((span) => this.transformSpanToProtobuf(span));
24741
24628
  const request = {
24742
24629
  observableServiceId: this.observableServiceId,
24743
- environment: this.environment,
24630
+ environment: this.environment || "",
24744
24631
  sdkVersion: this.sdkVersion,
24745
24632
  sdkInstanceId: this.sdkInstanceId,
24746
24633
  spans: protoSpans
@@ -24767,6 +24654,7 @@ var ApiSpanAdapter = class {
24767
24654
  instrumentationName: cleanSpan.instrumentationName,
24768
24655
  submoduleName: cleanSpan.submoduleName,
24769
24656
  packageType: cleanSpan.packageType || PackageType.UNSPECIFIED,
24657
+ environment: this.environment,
24770
24658
  inputValue: toStruct(cleanSpan.inputValue),
24771
24659
  outputValue: toStruct(cleanSpan.outputValue),
24772
24660
  inputSchema: cleanSpan.inputSchema,
@@ -24792,12 +24680,12 @@ var ApiSpanAdapter = class {
24792
24680
  }
24793
24681
  mapSpanKind(kind) {
24794
24682
  switch (kind) {
24795
- case import_src$7.SpanKind.CLIENT: return SpanKind.CLIENT;
24796
- case import_src$7.SpanKind.SERVER: return SpanKind.SERVER;
24797
- case import_src$7.SpanKind.PRODUCER: return SpanKind.PRODUCER;
24798
- case import_src$7.SpanKind.CONSUMER: return SpanKind.CONSUMER;
24799
- case import_src$7.SpanKind.INTERNAL: return SpanKind.INTERNAL;
24800
- default: return SpanKind.UNSPECIFIED;
24683
+ case import_src$7.SpanKind.CLIENT: return SpanKind$1.CLIENT;
24684
+ case import_src$7.SpanKind.SERVER: return SpanKind$1.SERVER;
24685
+ case import_src$7.SpanKind.PRODUCER: return SpanKind$1.PRODUCER;
24686
+ case import_src$7.SpanKind.CONSUMER: return SpanKind$1.CONSUMER;
24687
+ case import_src$7.SpanKind.INTERNAL: return SpanKind$1.INTERNAL;
24688
+ default: return SpanKind$1.UNSPECIFIED;
24801
24689
  }
24802
24690
  }
24803
24691
  async shutdown() {
@@ -24812,6 +24700,7 @@ var TdSpanExporter = class {
24812
24700
  constructor(config) {
24813
24701
  this.adapters = [];
24814
24702
  this.mode = config.mode;
24703
+ this.environment = config.environment;
24815
24704
  this.setupDefaultAdapters(config);
24816
24705
  logger.debug(`TdSpanExporter initialized with ${this.adapters.length} adapter(s)`);
24817
24706
  }
@@ -24895,7 +24784,7 @@ var TdSpanExporter = class {
24895
24784
  return true;
24896
24785
  });
24897
24786
  logger.debug(`Filtered ${filteredSpansBasedOnLibraryName.length - filteredBlockedSpans.length} blocked/oversized span(s), ${filteredBlockedSpans.length} remaining`);
24898
- const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span));
24787
+ const cleanSpans = filteredBlockedSpans.map((span) => SpanTransformer.transformSpanToCleanJSON(span, this.environment));
24899
24788
  if (this.adapters.length === 0) {
24900
24789
  logger.debug("No adapters configured");
24901
24790
  resultCallback({ code: import_src$5.ExportResultCode.SUCCESS });
@@ -32046,7 +31935,7 @@ var require_src = /* @__PURE__ */ __commonJS({ "node_modules/@opentelemetry/sdk-
32046
31935
  //#endregion
32047
31936
  //#region package.json
32048
31937
  var import_src$1 = /* @__PURE__ */ __toESM(require_src(), 1);
32049
- var version = "0.1.16";
31938
+ var version = "0.1.18";
32050
31939
 
32051
31940
  //#endregion
32052
31941
  //#region src/version.ts
@@ -32054,7 +31943,7 @@ const SDK_VERSION = version;
32054
31943
  const MIN_CLI_VERSION = "0.1.0";
32055
31944
 
32056
31945
  //#endregion
32057
- //#region node_modules/@use-tusk/drift-schemas/dist/communication-D4zqMBSI.js
31946
+ //#region node_modules/@use-tusk/drift-schemas/dist/communication-BY2KZhrg.js
32058
31947
  var import_commonjs = /* @__PURE__ */ __toESM(require_commonjs$1(), 1);
32059
31948
  var import_commonjs$1 = /* @__PURE__ */ __toESM(require_commonjs$2(), 1);
32060
31949
  /**
@@ -33198,12 +33087,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
33198
33087
  });
33199
33088
  await this.sendProtobufMessage(sdkMessage);
33200
33089
  }
33201
- getStackTrace() {
33202
- Error.stackTraceLimit = 100;
33203
- const s = (/* @__PURE__ */ new Error()).stack || "";
33204
- Error.stackTraceLimit = 10;
33205
- return s.split("\n").slice(2).filter((l) => !l.includes("ProtobufCommunicator")).join("\n");
33206
- }
33207
33090
  async requestMockAsync(mockRequest) {
33208
33091
  const requestId = this.generateRequestId();
33209
33092
  const cleanSpan = mockRequest.outboundSpan ? this.cleanSpan(mockRequest.outboundSpan) : void 0;
@@ -33236,7 +33119,7 @@ var ProtobufCommunicator = class ProtobufCommunicator {
33236
33119
  /**
33237
33120
  * Generic synchronous request handler that spawns a child process.
33238
33121
  * @param sdkMessage The SDK message to send
33239
- * @param filePrefix Prefix for temporary files (e.g., 'envvar', 'mock')
33122
+ * @param filePrefix Prefix for temporary files (e.g., 'mock')
33240
33123
  * @param responseHandler Function to extract and return the desired response
33241
33124
  */
33242
33125
  executeSyncRequest(sdkMessage, filePrefix, responseHandler) {
@@ -33305,35 +33188,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
33305
33188
  }
33306
33189
  }
33307
33190
  /**
33308
- * Request environment variables from CLI synchronously using a child process.
33309
- * This blocks the main thread, so it should be used carefully.
33310
- * Similar to requestMockSync but for environment variables.
33311
- */
33312
- requestEnvVarsSync(traceTestServerSpanId) {
33313
- const requestId = this.generateRequestId();
33314
- const envVarRequest = EnvVarRequest.create({ traceTestServerSpanId });
33315
- const sdkMessage = SDKMessage.create({
33316
- type: MessageType$1.ENV_VAR_REQUEST,
33317
- requestId,
33318
- payload: {
33319
- oneofKind: "envVarRequest",
33320
- envVarRequest
33321
- }
33322
- });
33323
- logger.debug(`[ProtobufCommunicator] Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
33324
- return this.executeSyncRequest(sdkMessage, "envvar", (cliMessage) => {
33325
- if (cliMessage.payload.oneofKind !== "envVarResponse") throw new Error(`Unexpected response type: ${cliMessage.type}`);
33326
- const envVarResponse = cliMessage.payload.envVarResponse;
33327
- if (!envVarResponse) throw new Error("No env var response received");
33328
- const envVars = {};
33329
- if (envVarResponse.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
33330
- envVars[key] = value;
33331
- });
33332
- logger.debug(`[ProtobufCommunicator] Received env vars (sync), count: ${Object.keys(envVars).length}`);
33333
- return envVars;
33334
- });
33335
- }
33336
- /**
33337
33191
  * This function uses a separate Node.js child process to communicate with the CLI over a socket.
33338
33192
  * The child process creates its own connection and event loop, allowing proper async socket handling.
33339
33193
  * The parent process blocks synchronously waiting for the child to complete.
@@ -33544,22 +33398,6 @@ var ProtobufCommunicator = class ProtobufCommunicator {
33544
33398
  error: mockResponse.error || "Mock not found"
33545
33399
  });
33546
33400
  }
33547
- if (message.payload.oneofKind === "envVarResponse") {
33548
- const envVarResponse = message.payload.envVarResponse;
33549
- logger.debug(`[ProtobufCommunicator] Received env var response for requestId: ${requestId}`);
33550
- const pendingRequest = this.pendingRequests.get(requestId);
33551
- if (!pendingRequest) {
33552
- logger.warn("[ProtobufCommunicator] received env var response for unknown request:", requestId);
33553
- return;
33554
- }
33555
- this.pendingRequests.delete(requestId);
33556
- const envVars = {};
33557
- if (envVarResponse?.envVars) Object.entries(envVarResponse.envVars).forEach(([key, value]) => {
33558
- envVars[key] = value;
33559
- });
33560
- pendingRequest.resolve(envVars);
33561
- return;
33562
- }
33563
33401
  }
33564
33402
  /**
33565
33403
  * Extract response data from MockResponse
@@ -33859,10 +33697,6 @@ var TuskDriftCore = class TuskDriftCore {
33859
33697
  enabled: true,
33860
33698
  mode: this.mode
33861
33699
  });
33862
- new EnvInstrumentation({
33863
- enabled: this.config.recording?.enable_env_var_recording || false,
33864
- mode: this.mode
33865
- });
33866
33700
  new PostgresInstrumentation({
33867
33701
  enabled: true,
33868
33702
  mode: this.mode
@@ -33910,7 +33744,7 @@ var TuskDriftCore = class TuskDriftCore {
33910
33744
  observableServiceId: this.config.service?.id,
33911
33745
  apiKey: this.initParams.apiKey,
33912
33746
  tuskBackendBaseUrl: this.config.tusk_api?.url || "https://api.usetusk.ai",
33913
- environment: this.initParams.env || "unknown",
33747
+ environment: this.initParams.env,
33914
33748
  sdkVersion: SDK_VERSION,
33915
33749
  sdkInstanceId: this.generateSdkInstanceId()
33916
33750
  });
@@ -33928,6 +33762,34 @@ var TuskDriftCore = class TuskDriftCore {
33928
33762
  generateSdkInstanceId() {
33929
33763
  return `sdk-${OriginalGlobalUtils.getOriginalDate().getTime()}-${Math.random().toString(36).substr(2, 9)}`;
33930
33764
  }
33765
+ /**
33766
+ * Creates a pre-app-start span containing a snapshot of all environment variables.
33767
+ * Only runs in RECORD mode when env var recording is enabled.
33768
+ */
33769
+ createEnvVarsSnapshot() {
33770
+ if (this.mode !== TuskDriftMode.RECORD || !this.config.recording?.enable_env_var_recording) return;
33771
+ try {
33772
+ const envVarsSnapshot = {};
33773
+ for (const key of Object.keys(process.env)) envVarsSnapshot[key] = process.env[key];
33774
+ logger.debug(`Creating env vars snapshot with ${Object.keys(envVarsSnapshot).length} variables`);
33775
+ SpanUtils.createAndExecuteSpan(this.mode, () => {}, {
33776
+ name: "ENV_VARS_SNAPSHOT",
33777
+ kind: import_src.SpanKind.INTERNAL,
33778
+ packageName: "process.env",
33779
+ packageType: PackageType.UNSPECIFIED,
33780
+ instrumentationName: "TuskDriftCore",
33781
+ submodule: "env",
33782
+ inputValue: {},
33783
+ outputValue: { ENV_VARS: envVarsSnapshot },
33784
+ isPreAppStart: true
33785
+ }, (spanInfo) => {
33786
+ SpanUtils.endSpan(spanInfo.span, { code: import_src.SpanStatusCode.OK });
33787
+ logger.debug(`Env vars snapshot span created: ${spanInfo.spanId}`);
33788
+ });
33789
+ } catch (error) {
33790
+ logger.error("Failed to create env vars snapshot:", error);
33791
+ }
33792
+ }
33931
33793
  initialize(initParams) {
33932
33794
  initializeGlobalLogger({
33933
33795
  logLevel: initParams.logLevel || "info",
@@ -34004,6 +33866,7 @@ var TuskDriftCore = class TuskDriftCore {
34004
33866
  logger.debug(`Base directory: ${baseDirectory}`);
34005
33867
  this.registerDefaultInstrumentations();
34006
33868
  this.initializeTracing({ baseDirectory });
33869
+ this.createEnvVarsSnapshot();
34007
33870
  this.initialized = true;
34008
33871
  logger.info("SDK initialized successfully");
34009
33872
  }
@@ -34067,30 +33930,6 @@ var TuskDriftCore = class TuskDriftCore {
34067
33930
  };
34068
33931
  }
34069
33932
  }
34070
- /**
34071
- * Request environment variables from CLI for a specific trace (synchronously).
34072
- * This blocks the main thread, so it should be used carefully.
34073
- */
34074
- requestEnvVarsSync(traceTestServerSpanId) {
34075
- if (!this.isConnectedWithCLI) {
34076
- logger.error("Requesting sync env vars but CLI is not ready yet");
34077
- throw new Error("Requesting sync env vars but CLI is not ready yet");
34078
- }
34079
- if (!this.communicator || this.mode !== TuskDriftMode.REPLAY) {
34080
- logger.debug("Cannot request env vars: not in replay mode or no CLI connection");
34081
- return {};
34082
- }
34083
- try {
34084
- logger.debug(`Requesting env vars (sync) for trace: ${traceTestServerSpanId}`);
34085
- const envVars = this.communicator.requestEnvVarsSync(traceTestServerSpanId);
34086
- logger.debug(`Received env vars from CLI, count: ${Object.keys(envVars).length}`);
34087
- logger.debug(`First 10 env vars: ${JSON.stringify(Object.keys(envVars).slice(0, 10), null, 2)}`);
34088
- return envVars;
34089
- } catch (error) {
34090
- logger.error(`[TuskDrift] Error requesting env vars from CLI:`, error);
34091
- return {};
34092
- }
34093
- }
34094
33933
  requestMockSync(mockRequest) {
34095
33934
  if (!this.isConnectedWithCLI) {
34096
33935
  logger.error("Requesting sync mock but CLI is not ready yet");
@@ -34142,6 +33981,9 @@ var TuskDriftCore = class TuskDriftCore {
34142
33981
  getInitParams() {
34143
33982
  return this.initParams;
34144
33983
  }
33984
+ getEnvironment() {
33985
+ return this.initParams.env;
33986
+ }
34145
33987
  getTracer() {
34146
33988
  return import_src.trace.getTracer(TD_INSTRUMENTATION_LIBRARY_NAME);
34147
33989
  }