@glasstrace/sdk 1.3.8 → 1.4.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.
Files changed (61) hide show
  1. package/README.md +68 -0
  2. package/dist/capture-error-BmQz7xF6.d.cts +455 -0
  3. package/dist/capture-error-CTgSYxek.d.ts +455 -0
  4. package/dist/{chunk-XS5W3SPL.js → chunk-4WI7B5FQ.js} +91 -5
  5. package/dist/chunk-4WI7B5FQ.js.map +1 -0
  6. package/dist/{chunk-NKRD3MKG.js → chunk-JZ475QRH.js} +2 -1
  7. package/dist/chunk-JZ475QRH.js.map +1 -0
  8. package/dist/{chunk-GYTCZSAV.js → chunk-MFYOQOD7.js} +2 -2
  9. package/dist/{chunk-4WUHMLMM.js → chunk-MMKFFF2L.js} +2 -2
  10. package/dist/{chunk-FKBCEOJ5.js → chunk-Q42BY5BA.js} +2 -2
  11. package/dist/{chunk-DBKG6SRI.js → chunk-QU26IKIJ.js} +2 -2
  12. package/dist/{chunk-ADUD4PEK.js → chunk-TANUWTFO.js} +3 -3
  13. package/dist/{chunk-LJMZXJ45.js → chunk-VJQIFY33.js} +3 -3
  14. package/dist/{chunk-E23HN24Z.js → chunk-VQDYXXVS.js} +9 -9
  15. package/dist/cli/init.cjs +14 -2
  16. package/dist/cli/init.cjs.map +1 -1
  17. package/dist/cli/init.js +7 -7
  18. package/dist/cli/mcp-add.cjs +13 -1
  19. package/dist/cli/mcp-add.cjs.map +1 -1
  20. package/dist/cli/mcp-add.js +3 -3
  21. package/dist/cli/uninit.js +3 -3
  22. package/dist/cli/validate.cjs +12 -1
  23. package/dist/cli/validate.cjs.map +1 -1
  24. package/dist/cli/validate.js +2 -2
  25. package/dist/{edge-entry-BSKA1l_0.d.ts → edge-entry-AWO70gje.d.ts} +1 -1
  26. package/dist/{edge-entry-DyMWa6JK.d.cts → edge-entry-DaeG7D7S.d.cts} +1 -1
  27. package/dist/edge-entry.cjs +43 -2
  28. package/dist/edge-entry.cjs.map +1 -1
  29. package/dist/edge-entry.d.cts +2 -2
  30. package/dist/edge-entry.d.ts +2 -2
  31. package/dist/edge-entry.js +2 -2
  32. package/dist/index.cjs +369 -8
  33. package/dist/index.cjs.map +1 -1
  34. package/dist/{index.d-Bo_Rxund.d.cts → index.d-Dq33YwFT.d.cts} +91 -1
  35. package/dist/{index.d-Bo_Rxund.d.ts → index.d-Dq33YwFT.d.ts} +91 -1
  36. package/dist/index.d.cts +91 -431
  37. package/dist/index.d.ts +91 -431
  38. package/dist/index.js +290 -6
  39. package/dist/index.js.map +1 -1
  40. package/dist/node-entry.cjs +49 -7
  41. package/dist/node-entry.cjs.map +1 -1
  42. package/dist/node-entry.d.cts +3 -3
  43. package/dist/node-entry.d.ts +3 -3
  44. package/dist/node-entry.js +7 -7
  45. package/dist/node-subpath.cjs +12 -1
  46. package/dist/node-subpath.cjs.map +1 -1
  47. package/dist/node-subpath.d.cts +1 -1
  48. package/dist/node-subpath.d.ts +1 -1
  49. package/dist/node-subpath.js +3 -3
  50. package/dist/{source-map-uploader-FSTHCYDR.js → source-map-uploader-PB3M4PPP.js} +3 -3
  51. package/package.json +1 -1
  52. package/dist/chunk-NKRD3MKG.js.map +0 -1
  53. package/dist/chunk-XS5W3SPL.js.map +0 -1
  54. /package/dist/{chunk-GYTCZSAV.js.map → chunk-MFYOQOD7.js.map} +0 -0
  55. /package/dist/{chunk-4WUHMLMM.js.map → chunk-MMKFFF2L.js.map} +0 -0
  56. /package/dist/{chunk-FKBCEOJ5.js.map → chunk-Q42BY5BA.js.map} +0 -0
  57. /package/dist/{chunk-DBKG6SRI.js.map → chunk-QU26IKIJ.js.map} +0 -0
  58. /package/dist/{chunk-ADUD4PEK.js.map → chunk-TANUWTFO.js.map} +0 -0
  59. /package/dist/{chunk-LJMZXJ45.js.map → chunk-VJQIFY33.js.map} +0 -0
  60. /package/dist/{chunk-E23HN24Z.js.map → chunk-VQDYXXVS.js.map} +0 -0
  61. /package/dist/{source-map-uploader-FSTHCYDR.js.map → source-map-uploader-PB3M4PPP.js.map} +0 -0
@@ -1,5 +1,5 @@
1
- export { C as CorrelationIdRequest, G as GlasstraceSpanProcessor, S as SdkError, c as captureCorrelationId } from './edge-entry-DyMWa6JK.cjs';
2
- import './index.d-Bo_Rxund.cjs';
1
+ export { C as CorrelationIdRequest, G as GlasstraceSpanProcessor, S as SdkError, c as captureCorrelationId } from './edge-entry-DaeG7D7S.cjs';
2
+ import './index.d-Dq33YwFT.cjs';
3
3
  import './v4/classic/external.cjs';
4
4
  import './export/ReadableSpan';
5
5
  import './Span';
@@ -1,5 +1,5 @@
1
- export { C as CorrelationIdRequest, G as GlasstraceSpanProcessor, S as SdkError, c as captureCorrelationId } from './edge-entry-BSKA1l_0.js';
2
- import './index.d-Bo_Rxund.js';
1
+ export { C as CorrelationIdRequest, G as GlasstraceSpanProcessor, S as SdkError, c as captureCorrelationId } from './edge-entry-AWO70gje.js';
2
+ import './index.d-Dq33YwFT.js';
3
3
  import './v4/classic/external.cjs';
4
4
  import './export/ReadableSpan';
5
5
  import './Span';
@@ -2,9 +2,9 @@ import {
2
2
  GlasstraceSpanProcessor,
3
3
  SdkError,
4
4
  captureCorrelationId
5
- } from "./chunk-FKBCEOJ5.js";
5
+ } from "./chunk-Q42BY5BA.js";
6
6
  import "./chunk-DQ25VOKK.js";
7
- import "./chunk-XS5W3SPL.js";
7
+ import "./chunk-4WI7B5FQ.js";
8
8
  import "./chunk-NSBPE2FW.js";
9
9
  export {
10
10
  GlasstraceSpanProcessor,
package/dist/index.cjs CHANGED
@@ -14563,7 +14563,7 @@ function deriveSessionId(apiKey, origin, date5, windowIndex) {
14563
14563
  const digest = sha256Hex(input).slice(0, 16);
14564
14564
  return SessionIdSchema.parse(digest);
14565
14565
  }
14566
- var DevApiKeySchema, AnonApiKeySchema, SessionIdSchema, BuildHashSchema, SdkDiagnosticCodeSchema, CaptureConfigSchema, SdkCachedConfigSchema, GlasstraceOptionsSchema, GlasstraceEnvVarsSchema, GLASSTRACE_ATTRIBUTE_NAMES, DEFAULT_CAPTURE_CONFIG, MAX_SOURCE_MAP_FILE_PATH_LENGTH, MAX_SOURCE_MAP_FILE_SIZE, MAX_SOURCE_MAP_FILE_COUNT, MAX_PRESIGNED_CLIENT_TOKEN_LENGTH, MAX_PRESIGNED_PATHNAME_LENGTH, ImportGraphPayloadSchema, SdkHealthReportSchema, TierLimitsSchema, SdkInitResponseSchema, DiscoveryResponseSchema, SourceMapUploadResponseSchema, PresignedUploadRequestSchema, PresignedUploadResponseSchema, SourceMapManifestRequestSchema, SourceMapManifestResponseSchema, K;
14566
+ var DevApiKeySchema, AnonApiKeySchema, SessionIdSchema, BuildHashSchema, SdkDiagnosticCodeSchema, CaptureConfigSchema, SdkCachedConfigSchema, GlasstraceOptionsSchema, GlasstraceEnvVarsSchema, GLASSTRACE_ATTRIBUTE_NAMES, DEFAULT_CAPTURE_CONFIG, MAX_SOURCE_MAP_FILE_PATH_LENGTH, MAX_SOURCE_MAP_FILE_SIZE, MAX_SOURCE_MAP_FILE_COUNT, MAX_PRESIGNED_CLIENT_TOKEN_LENGTH, MAX_PRESIGNED_PATHNAME_LENGTH, ImportGraphPayloadSchema, SdkHealthReportSchema, TierLimitsSchema, SdkInitResponseSchema, DiscoveryResponseSchema, SourceMapUploadResponseSchema, PresignedUploadRequestSchema, PresignedUploadResponseSchema, SourceMapManifestRequestSchema, SourceMapManifestResponseSchema, K, SIDE_EFFECT_OPERATION_KINDS, SIDE_EFFECT_SEMANTIC_FIELD_KEYS, SIDE_EFFECT_OMISSION_REASONS, SIDE_EFFECT_OPERATION_STATUSES, SIDE_EFFECT_OPERATION_PHASES;
14567
14567
  var init_dist = __esm({
14568
14568
  "../protocol/dist/index.js"() {
14569
14569
  "use strict";
@@ -14591,7 +14591,18 @@ var init_dist = __esm({
14591
14591
  fullConsoleOutput: external_exports.boolean(),
14592
14592
  importGraph: external_exports.boolean(),
14593
14593
  consoleErrors: external_exports.boolean().optional().default(false),
14594
- errorResponseBodies: external_exports.boolean().optional().default(false)
14594
+ errorResponseBodies: external_exports.boolean().optional().default(false),
14595
+ /**
14596
+ * Account opt-in for side-effect evidence emission (SDK-049).
14597
+ *
14598
+ * When `false` (default), `recordSideEffect()` is a silent no-op:
14599
+ * no allowlist evaluation runs and no `glasstrace.side_effect.*`
14600
+ * attribute reaches the wire. When `true`, allowlisted side-effect
14601
+ * metadata is attached to the active OTel span subject to the
14602
+ * client-side allowlist enforcement layered with the product's
14603
+ * storage-time filter as defense-in-depth.
14604
+ */
14605
+ sideEffectEvidence: external_exports.boolean().optional().default(false)
14595
14606
  });
14596
14607
  SdkCachedConfigSchema = external_exports.object({
14597
14608
  response: external_exports.record(external_exports.string(), external_exports.unknown()),
@@ -14651,7 +14662,37 @@ var init_dist = __esm({
14651
14662
  TRIGGER_TYPE: "glasstrace.trigger.type",
14652
14663
  ELEMENT_FINGERPRINT: "glasstrace.element.fingerprint",
14653
14664
  ELEMENT_CONFIDENCE: "glasstrace.element.confidence",
14654
- TAB_ID: "glasstrace.tab.id"
14665
+ TAB_ID: "glasstrace.tab.id",
14666
+ // Side-effect evidence (SDK-049 / SCHEMA-036).
14667
+ // Top-level operation attributes attached to the active span when a
14668
+ // side-effect is recorded via `recordSideEffect()`. The wire-string
14669
+ // set aligns verbatim with the product-side filter in
14670
+ // `packages/ingestion/src/services/trace-writer.ts`.
14671
+ SIDE_EFFECT_KIND: "glasstrace.side_effect.kind",
14672
+ SIDE_EFFECT_OPERATION: "glasstrace.side_effect.operation",
14673
+ SIDE_EFFECT_STATUS: "glasstrace.side_effect.status",
14674
+ SIDE_EFFECT_PHASE: "glasstrace.side_effect.phase",
14675
+ // Allowlisted semantic field attributes — one per allowlisted key.
14676
+ // Wire keys are camelCase to match the SCHEMA-036 enum members
14677
+ // exactly; the SDK constant names are SCREAMING_SNAKE per the rest
14678
+ // of GLASSTRACE_ATTRIBUTE_NAMES.
14679
+ SIDE_EFFECT_FIELD_TEMPLATE_KEY: "glasstrace.side_effect.field.templateKey",
14680
+ SIDE_EFFECT_FIELD_PROVIDER_OPERATION: "glasstrace.side_effect.field.providerOperation",
14681
+ SIDE_EFFECT_FIELD_ROLE: "glasstrace.side_effect.field.role",
14682
+ SIDE_EFFECT_FIELD_LOCALE: "glasstrace.side_effect.field.locale",
14683
+ SIDE_EFFECT_FIELD_TIMEZONE: "glasstrace.side_effect.field.timezone",
14684
+ SIDE_EFFECT_FIELD_STATUS: "glasstrace.side_effect.field.status",
14685
+ SIDE_EFFECT_FIELD_PHASE: "glasstrace.side_effect.field.phase",
14686
+ // Omission reason attributes — one per allowlisted reason. The
14687
+ // attribute value carries an integer count; the rejected value is
14688
+ // never echoed.
14689
+ SIDE_EFFECT_OMITTED_PII: "glasstrace.side_effect.omitted.pii",
14690
+ SIDE_EFFECT_OMITTED_SECRET: "glasstrace.side_effect.omitted.secret",
14691
+ SIDE_EFFECT_OMITTED_RAW_PAYLOAD: "glasstrace.side_effect.omitted.raw_payload",
14692
+ SIDE_EFFECT_OMITTED_UNSUPPORTED_KEY: "glasstrace.side_effect.omitted.unsupported_key",
14693
+ SIDE_EFFECT_OMITTED_VALUE_TOO_LONG: "glasstrace.side_effect.omitted.value_too_long",
14694
+ SIDE_EFFECT_OMITTED_NOT_EMITTED: "glasstrace.side_effect.omitted.not_emitted",
14695
+ SIDE_EFFECT_OMITTED_CAPTURE_DISABLED: "glasstrace.side_effect.omitted.capture_disabled"
14655
14696
  };
14656
14697
  DEFAULT_CAPTURE_CONFIG = {
14657
14698
  requestBodies: false,
@@ -14660,7 +14701,8 @@ var init_dist = __esm({
14660
14701
  fullConsoleOutput: false,
14661
14702
  importGraph: false,
14662
14703
  consoleErrors: false,
14663
- errorResponseBodies: false
14704
+ errorResponseBodies: false,
14705
+ sideEffectEvidence: false
14664
14706
  };
14665
14707
  MAX_SOURCE_MAP_FILE_PATH_LENGTH = 512;
14666
14708
  MAX_SOURCE_MAP_FILE_SIZE = 50 * 1024 * 1024;
@@ -14849,6 +14891,45 @@ var init_dist = __esm({
14849
14891
  3204031479,
14850
14892
  3329325298
14851
14893
  ]);
14894
+ SIDE_EFFECT_OPERATION_KINDS = [
14895
+ "email",
14896
+ "calendar_link",
14897
+ "webhook",
14898
+ "external_api",
14899
+ "queue",
14900
+ "after_callback"
14901
+ ];
14902
+ SIDE_EFFECT_SEMANTIC_FIELD_KEYS = [
14903
+ "templateKey",
14904
+ "providerOperation",
14905
+ "role",
14906
+ "locale",
14907
+ "timezone",
14908
+ "status",
14909
+ "phase"
14910
+ ];
14911
+ SIDE_EFFECT_OMISSION_REASONS = [
14912
+ "pii",
14913
+ "secret",
14914
+ "raw_payload",
14915
+ "unsupported_key",
14916
+ "value_too_long",
14917
+ "not_emitted",
14918
+ "capture_disabled"
14919
+ ];
14920
+ SIDE_EFFECT_OPERATION_STATUSES = [
14921
+ "scheduled",
14922
+ "started",
14923
+ "succeeded",
14924
+ "failed",
14925
+ "unknown"
14926
+ ];
14927
+ SIDE_EFFECT_OPERATION_PHASES = [
14928
+ "request",
14929
+ "post_response",
14930
+ "background",
14931
+ "unknown"
14932
+ ];
14852
14933
  }
14853
14934
  });
14854
14935
 
@@ -16934,6 +17015,7 @@ __export(src_exports, {
16934
17015
  performInit: () => performInit,
16935
17016
  readAnonKey: () => readAnonKey,
16936
17017
  readEnvVars: () => readEnvVars,
17018
+ recordSideEffect: () => recordSideEffect,
16937
17019
  registerGlasstrace: () => registerGlasstrace,
16938
17020
  resolveConfig: () => resolveConfig,
16939
17021
  saveCachedConfig: () => saveCachedConfig,
@@ -22677,7 +22759,7 @@ function registerGlasstrace(options) {
22677
22759
  setCoreState(CoreState.REGISTERING);
22678
22760
  startRuntimeStateWriter({
22679
22761
  projectRoot: process.cwd(),
22680
- sdkVersion: "1.3.8"
22762
+ sdkVersion: "1.4.0"
22681
22763
  });
22682
22764
  const config2 = resolveConfig(options);
22683
22765
  if (config2.verbose) {
@@ -22844,8 +22926,8 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22844
22926
  if (config2.verbose) {
22845
22927
  console.info("[glasstrace] Background init firing.");
22846
22928
  }
22847
- const healthReport = collectHealthReport("1.3.8");
22848
- const initResult = await performInit(config2, anonKeyForInit, "1.3.8", healthReport);
22929
+ const healthReport = collectHealthReport("1.4.0");
22930
+ const initResult = await performInit(config2, anonKeyForInit, "1.4.0", healthReport);
22849
22931
  if (generation !== registrationGeneration) return;
22850
22932
  const currentState = getCoreState();
22851
22933
  if (currentState === CoreState.SHUTTING_DOWN || currentState === CoreState.SHUTDOWN) {
@@ -22868,7 +22950,7 @@ async function backgroundInit(config2, anonKeyForInit, generation) {
22868
22950
  }
22869
22951
  maybeInstallConsoleCapture();
22870
22952
  if (didLastInitSucceed()) {
22871
- startHeartbeat(config2, anonKeyForInit, "1.3.8", generation, (newApiKey, accountId) => {
22953
+ startHeartbeat(config2, anonKeyForInit, "1.4.0", generation, (newApiKey, accountId) => {
22872
22954
  setAuthState(AuthState.CLAIMING);
22873
22955
  emitLifecycleEvent("auth:claim_started", { accountId });
22874
22956
  setResolvedApiKey(newApiKey);
@@ -23160,6 +23242,284 @@ function firstToken(value) {
23160
23242
  }
23161
23243
  return void 0;
23162
23244
  }
23245
+
23246
+ // src/side-effect/allowlist.ts
23247
+ init_dist();
23248
+ var MAX_SIDE_EFFECT_OPERATION_LABEL_LENGTH = 96;
23249
+ var MAX_SIDE_EFFECT_FIELD_VALUE_LENGTH = 80;
23250
+ var MAX_SIDE_EFFECT_OPERATIONS_PER_SPAN = 5;
23251
+ var OPERATION_KIND_SET = new Set(
23252
+ SIDE_EFFECT_OPERATION_KINDS
23253
+ );
23254
+ var SEMANTIC_FIELD_KEY_SET = new Set(
23255
+ SIDE_EFFECT_SEMANTIC_FIELD_KEYS
23256
+ );
23257
+ var OPERATION_STATUS_SET = new Set(
23258
+ SIDE_EFFECT_OPERATION_STATUSES
23259
+ );
23260
+ var OPERATION_PHASE_SET = new Set(
23261
+ SIDE_EFFECT_OPERATION_PHASES
23262
+ );
23263
+ var OMISSION_REASON_SET = new Set(
23264
+ SIDE_EFFECT_OMISSION_REASONS
23265
+ );
23266
+ var TOKEN_REGEX = /^[A-Za-z0-9][A-Za-z0-9_.:-]*$/;
23267
+ var LOCALE_REGEX = /^[A-Za-z]{2,3}(?:-[A-Za-z0-9]{2,8}){0,3}$/;
23268
+ var TIMEZONE_REGEX = /^(?:UTC|GMT|[A-Za-z][A-Za-z0-9_+-]*(?:\/[A-Za-z0-9_+-]+){1,3})$/;
23269
+ var URL_SCHEME = /:\/\//;
23270
+ var URL_SCHEME_RELATIVE = /^\/\//;
23271
+ var EMAIL_LIKE = /[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/i;
23272
+ var QUERY_LIKE = /\?/;
23273
+ var FRAGMENT_LIKE = /#/;
23274
+ var HEADER_LIKE = /\b(authorization|set-cookie|cookie)\b\s*[:=]/i;
23275
+ var HEADER_TOKEN_LIKE = /\b(authorization|set-cookie|cookie)\b\s+\S+=/i;
23276
+ var BEARER_LIKE = /bearer\s+\S+/i;
23277
+ var TOKEN_KV_LIKE = /["']?(password|passwd|token|api[_-]?key|secret|client_secret)["']?\s*[:=]/i;
23278
+ var PROSE_LIKE = /[\r\n\t]|\s{2,}/;
23279
+ var UUID_LIKE = /[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}/i;
23280
+ var GT_KEY_LIKE = /gt_(dev|anon|live)_[A-Za-z0-9_-]+/;
23281
+ function detectUnsafePattern(value) {
23282
+ if (value.trim() !== value) return "raw_payload";
23283
+ if (PROSE_LIKE.test(value)) return "raw_payload";
23284
+ if (URL_SCHEME.test(value)) return "raw_payload";
23285
+ if (URL_SCHEME_RELATIVE.test(value)) return "raw_payload";
23286
+ if (QUERY_LIKE.test(value)) return "raw_payload";
23287
+ if (FRAGMENT_LIKE.test(value)) return "raw_payload";
23288
+ if (BEARER_LIKE.test(value)) return "secret";
23289
+ if (HEADER_TOKEN_LIKE.test(value)) return "secret";
23290
+ if (TOKEN_KV_LIKE.test(value)) return "secret";
23291
+ if (HEADER_LIKE.test(value)) return "secret";
23292
+ if (UUID_LIKE.test(value)) return "secret";
23293
+ if (GT_KEY_LIKE.test(value)) return "secret";
23294
+ if (EMAIL_LIKE.test(value)) return "pii";
23295
+ return null;
23296
+ }
23297
+ function passesFieldValidator(key, value) {
23298
+ if (key === "locale") return LOCALE_REGEX.test(value);
23299
+ if (key === "timezone") return TIMEZONE_REGEX.test(value);
23300
+ return TOKEN_REGEX.test(value);
23301
+ }
23302
+ function checkOperationLabel(value) {
23303
+ if (typeof value !== "string" || value.length === 0) {
23304
+ return { accepted: false, reason: "raw_payload" };
23305
+ }
23306
+ if (value.length > MAX_SIDE_EFFECT_OPERATION_LABEL_LENGTH) {
23307
+ return { accepted: false, reason: "value_too_long" };
23308
+ }
23309
+ const unsafe = detectUnsafePattern(value);
23310
+ if (unsafe) {
23311
+ return { accepted: false, reason: unsafe };
23312
+ }
23313
+ if (!TOKEN_REGEX.test(value)) {
23314
+ return { accepted: false, reason: "raw_payload" };
23315
+ }
23316
+ return { accepted: true, value };
23317
+ }
23318
+ function checkSemanticFieldValue(key, value) {
23319
+ if (typeof value !== "string" || value.length === 0) {
23320
+ return { accepted: false, reason: "raw_payload" };
23321
+ }
23322
+ if (value.length > MAX_SIDE_EFFECT_FIELD_VALUE_LENGTH) {
23323
+ return { accepted: false, reason: "value_too_long" };
23324
+ }
23325
+ const unsafe = detectUnsafePattern(value);
23326
+ if (unsafe) {
23327
+ return { accepted: false, reason: unsafe };
23328
+ }
23329
+ if (!passesFieldValidator(key, value)) {
23330
+ return { accepted: false, reason: "raw_payload" };
23331
+ }
23332
+ return { accepted: true, value };
23333
+ }
23334
+ function checkSemanticFieldKey(key) {
23335
+ return typeof key === "string" && SEMANTIC_FIELD_KEY_SET.has(key);
23336
+ }
23337
+ function checkOperationKind(kind) {
23338
+ return typeof kind === "string" && OPERATION_KIND_SET.has(kind);
23339
+ }
23340
+ function checkOperationStatus(status) {
23341
+ return typeof status === "string" && OPERATION_STATUS_SET.has(status);
23342
+ }
23343
+ function checkOperationPhase(phase) {
23344
+ return typeof phase === "string" && OPERATION_PHASE_SET.has(phase);
23345
+ }
23346
+
23347
+ // src/side-effect/emit.ts
23348
+ init_esm();
23349
+ init_dist();
23350
+ var spanState = /* @__PURE__ */ new WeakMap();
23351
+ function getOrCreateState(span) {
23352
+ let state = spanState.get(span);
23353
+ if (!state) {
23354
+ state = { operationsRecorded: 0, omissions: /* @__PURE__ */ new Map() };
23355
+ spanState.set(span, state);
23356
+ }
23357
+ return state;
23358
+ }
23359
+ function getRecordingActiveSpan() {
23360
+ let span;
23361
+ try {
23362
+ span = trace.getActiveSpan();
23363
+ } catch {
23364
+ return void 0;
23365
+ }
23366
+ if (!span) return void 0;
23367
+ try {
23368
+ if (typeof span.isRecording === "function" && !span.isRecording()) {
23369
+ return void 0;
23370
+ }
23371
+ } catch {
23372
+ return void 0;
23373
+ }
23374
+ return span;
23375
+ }
23376
+ function recordOmissionOnActiveSpan(reason) {
23377
+ const span = getRecordingActiveSpan();
23378
+ if (!span) return;
23379
+ recordOmissionOnSpan(span, reason);
23380
+ }
23381
+ function recordOmissionOnSpan(span, reason) {
23382
+ const state = getOrCreateState(span);
23383
+ const previous = state.omissions.get(reason) ?? 0;
23384
+ const next = previous + 1;
23385
+ state.omissions.set(reason, next);
23386
+ const attribute = OMISSION_ATTRIBUTE_BY_REASON[reason];
23387
+ try {
23388
+ span.setAttribute(attribute, next);
23389
+ } catch {
23390
+ }
23391
+ }
23392
+ var OMISSION_ATTRIBUTE_BY_REASON = {
23393
+ pii: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_PII,
23394
+ secret: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_SECRET,
23395
+ raw_payload: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_RAW_PAYLOAD,
23396
+ unsupported_key: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_UNSUPPORTED_KEY,
23397
+ value_too_long: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_VALUE_TOO_LONG,
23398
+ not_emitted: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_NOT_EMITTED,
23399
+ capture_disabled: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OMITTED_CAPTURE_DISABLED
23400
+ };
23401
+ var FIELD_ATTRIBUTE_BY_KEY = {
23402
+ templateKey: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_TEMPLATE_KEY,
23403
+ providerOperation: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_PROVIDER_OPERATION,
23404
+ role: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_ROLE,
23405
+ locale: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_LOCALE,
23406
+ timezone: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_TIMEZONE,
23407
+ status: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_STATUS,
23408
+ phase: GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_FIELD_PHASE
23409
+ };
23410
+ function attachOperation(input) {
23411
+ const span = getRecordingActiveSpan();
23412
+ if (!span) return { kind: "no_active_span" };
23413
+ const state = getOrCreateState(span);
23414
+ if (state.operationsRecorded >= MAX_SIDE_EFFECT_OPERATIONS_PER_SPAN) {
23415
+ return { kind: "over_budget", span };
23416
+ }
23417
+ state.operationsRecorded += 1;
23418
+ try {
23419
+ span.setAttribute(GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_KIND, input.kind);
23420
+ span.setAttribute(
23421
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_OPERATION,
23422
+ input.operation
23423
+ );
23424
+ if (input.status !== void 0) {
23425
+ span.setAttribute(
23426
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_STATUS,
23427
+ input.status
23428
+ );
23429
+ }
23430
+ if (input.phase !== void 0) {
23431
+ span.setAttribute(
23432
+ GLASSTRACE_ATTRIBUTE_NAMES.SIDE_EFFECT_PHASE,
23433
+ input.phase
23434
+ );
23435
+ }
23436
+ } catch {
23437
+ }
23438
+ return { kind: "attached", span };
23439
+ }
23440
+ function attachField(span, key, value) {
23441
+ const attribute = FIELD_ATTRIBUTE_BY_KEY[key];
23442
+ try {
23443
+ span.setAttribute(attribute, value);
23444
+ } catch {
23445
+ }
23446
+ }
23447
+ function recordOmission(span, reason) {
23448
+ recordOmissionOnSpan(span, reason);
23449
+ }
23450
+
23451
+ // src/side-effect/index.ts
23452
+ function recordSideEffect(input) {
23453
+ try {
23454
+ runRecordSideEffect(input);
23455
+ } catch {
23456
+ }
23457
+ }
23458
+ function runRecordSideEffect(input) {
23459
+ if (!input || typeof input !== "object") return;
23460
+ let captureEnabled;
23461
+ try {
23462
+ captureEnabled = getActiveConfig().sideEffectEvidence === true;
23463
+ } catch {
23464
+ captureEnabled = false;
23465
+ }
23466
+ if (!captureEnabled) {
23467
+ return;
23468
+ }
23469
+ const candidate = input;
23470
+ if (!checkOperationKind(candidate.kind)) {
23471
+ return;
23472
+ }
23473
+ const labelOutcome = checkOperationLabel(candidate.operation);
23474
+ if (!labelOutcome.accepted) {
23475
+ recordOmissionOnActiveSpan(labelOutcome.reason);
23476
+ return;
23477
+ }
23478
+ let acceptedStatus;
23479
+ if (candidate.status !== void 0) {
23480
+ if (checkOperationStatus(candidate.status)) {
23481
+ acceptedStatus = candidate.status;
23482
+ } else {
23483
+ recordOmissionOnActiveSpan("unsupported_key");
23484
+ }
23485
+ }
23486
+ let acceptedPhase;
23487
+ if (candidate.phase !== void 0) {
23488
+ if (checkOperationPhase(candidate.phase)) {
23489
+ acceptedPhase = candidate.phase;
23490
+ } else {
23491
+ recordOmissionOnActiveSpan("unsupported_key");
23492
+ }
23493
+ }
23494
+ const outcome = attachOperation({
23495
+ kind: candidate.kind,
23496
+ operation: labelOutcome.value,
23497
+ status: acceptedStatus,
23498
+ phase: acceptedPhase
23499
+ });
23500
+ if (outcome.kind === "no_active_span") {
23501
+ return;
23502
+ }
23503
+ if (outcome.kind === "over_budget") {
23504
+ recordOmission(outcome.span, "value_too_long");
23505
+ return;
23506
+ }
23507
+ const fields = candidate.fields;
23508
+ if (fields && typeof fields === "object") {
23509
+ for (const [rawKey, rawValue] of Object.entries(fields)) {
23510
+ if (!checkSemanticFieldKey(rawKey)) {
23511
+ recordOmission(outcome.span, "unsupported_key");
23512
+ continue;
23513
+ }
23514
+ const valueOutcome = checkSemanticFieldValue(rawKey, rawValue);
23515
+ if (!valueOutcome.accepted) {
23516
+ recordOmission(outcome.span, valueOutcome.reason);
23517
+ continue;
23518
+ }
23519
+ attachField(outcome.span, rawKey, valueOutcome.value);
23520
+ }
23521
+ }
23522
+ }
23163
23523
  // Annotate the CommonJS export names for ESM import in node:
23164
23524
  0 && (module.exports = {
23165
23525
  GlasstraceExporter,
@@ -23185,6 +23545,7 @@ function firstToken(value) {
23185
23545
  performInit,
23186
23546
  readAnonKey,
23187
23547
  readEnvVars,
23548
+ recordSideEffect,
23188
23549
  registerGlasstrace,
23189
23550
  resolveConfig,
23190
23551
  saveCachedConfig,