@capxul/sdk 1.0.0-alpha.16 → 1.0.0-alpha.17

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.mjs CHANGED
@@ -1600,7 +1600,7 @@ async function recoverRawDigestSigner(input) {
1600
1600
  }
1601
1601
  //#endregion
1602
1602
  //#region package.json
1603
- var version = "1.0.0-alpha.16";
1603
+ var version = "1.0.0-alpha.17";
1604
1604
  //#endregion
1605
1605
  //#region src/ports/auth-client.ts
1606
1606
  var AuthClientError = class extends Data.TaggedError("AuthClientError") {};
@@ -1646,6 +1646,85 @@ function resolveAuthClientUrl(authBaseUrl, path) {
1646
1646
  return `${base}${path}`;
1647
1647
  }
1648
1648
  //#endregion
1649
+ //#region ../wire/src/observation-context.ts
1650
+ /** Single bounded HTTP carrier used before a Convex action envelope exists. */
1651
+ const OBSERVATION_CONTEXT_HEADER = "x-capxul-observation-context";
1652
+ const FIELD_RULES = {
1653
+ application: {
1654
+ maxLength: 64,
1655
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._-]*$/u
1656
+ },
1657
+ applicationId: {
1658
+ maxLength: 30,
1659
+ pattern: APP_ID_RE
1660
+ },
1661
+ release: {
1662
+ maxLength: 128,
1663
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._+@:/-]*$/u
1664
+ },
1665
+ sessionId: {
1666
+ maxLength: 128,
1667
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1668
+ },
1669
+ organizationId: {
1670
+ maxLength: 128,
1671
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1672
+ },
1673
+ correlationId: {
1674
+ maxLength: 128,
1675
+ pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
1676
+ },
1677
+ anonymousId: {
1678
+ maxLength: 128,
1679
+ pattern: /^anon_[A-Za-z0-9-]+$/u
1680
+ }
1681
+ };
1682
+ const EMBEDDED_WALLET_MATERIAL = /0x[a-fA-F0-9]{40,}/u;
1683
+ const RAW_PRIVATE_KEY_MATERIAL = /(?:^|[^a-fA-F0-9])[a-fA-F0-9]{64}(?:$|[^a-fA-F0-9])/u;
1684
+ const COMPACT_JWT = /eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/u;
1685
+ const KNOWN_CREDENTIAL_PREFIX = /(?:(?:sk|pk|rk)_(?:live|test)|(?:phc|phx|ghp|gho|ghu|ghs|ghr|whsec)_|github_pat_|xox[baprs]-|AKIA[0-9A-Z]{16}|AIza)[A-Za-z0-9_-]*/iu;
1686
+ /**
1687
+ * Copy only the canonical allowlist and silently omit malformed/sensitive
1688
+ * values. Observation metadata is best effort and may never reject a domain
1689
+ * operation.
1690
+ */
1691
+ function sanitizeObservationContext(input) {
1692
+ if (typeof input !== "object" || input === null || Array.isArray(input)) return void 0;
1693
+ const source = input;
1694
+ const sanitized = {};
1695
+ for (const field of Object.keys(FIELD_RULES)) {
1696
+ const value = source[field];
1697
+ if (!isSafeField(field, value)) continue;
1698
+ sanitized[field] = value;
1699
+ }
1700
+ return Object.keys(sanitized).length === 0 ? void 0 : sanitized;
1701
+ }
1702
+ /** Encode only the sanitized allowlist; absence stays absence. */
1703
+ function encodeObservationContextHeader(input) {
1704
+ const sanitized = sanitizeObservationContext(input);
1705
+ return sanitized === void 0 ? void 0 : JSON.stringify(sanitized);
1706
+ }
1707
+ function isSafeField(field, value) {
1708
+ if (typeof value !== "string") return false;
1709
+ const rule = FIELD_RULES[field];
1710
+ return value.length > 0 && value.length <= rule.maxLength && value === value.trim() && !value.includes("://") && !containsSensitiveMaterial(value) && rule.pattern.test(value);
1711
+ }
1712
+ function containsSensitiveMaterial(value) {
1713
+ return EMBEDDED_WALLET_MATERIAL.test(value) || RAW_PRIVATE_KEY_MATERIAL.test(value) || COMPACT_JWT.test(value) || KNOWN_CREDENTIAL_PREFIX.test(value);
1714
+ }
1715
+ //#endregion
1716
+ //#region src/internal/observation-http.ts
1717
+ /** Resolve one bounded pre-auth snapshot for an outbound SDK HTTP request. */
1718
+ function observationRequestHeaders(adapter) {
1719
+ if (adapter === void 0) return {};
1720
+ try {
1721
+ const encoded = encodeObservationContextHeader(adapter.resolveContext?.());
1722
+ return encoded === void 0 ? {} : { [OBSERVATION_CONTEXT_HEADER]: encoded };
1723
+ } catch {
1724
+ return {};
1725
+ }
1726
+ }
1727
+ //#endregion
1649
1728
  //#region src/adapters/auth-client/BetterAuthBrowserAdapter.ts
1650
1729
  function withSignal$1(init, signal) {
1651
1730
  return signal === void 0 ? init : {
@@ -1703,8 +1782,10 @@ function mapFetchError$1(operation, err, signal) {
1703
1782
  var BetterAuthBrowserAdapter = class {
1704
1783
  authBaseUrl;
1705
1784
  fetchImpl;
1785
+ observation;
1706
1786
  constructor(deps) {
1707
1787
  this.authBaseUrl = deps.authBaseUrl.replace(/\/$/, "");
1788
+ this.observation = deps.observation;
1708
1789
  this.fetchImpl = deps.fetch ?? ((input, init) => globalThis.fetch(input, init));
1709
1790
  }
1710
1791
  url(path) {
@@ -1731,7 +1812,10 @@ var BetterAuthBrowserAdapter = class {
1731
1812
  try {
1732
1813
  const res = await this.fetchImpl(this.url("/api/auth/email-otp/send-verification-otp"), withSignal$1({
1733
1814
  method: "POST",
1734
- headers: { "Content-Type": "application/json" },
1815
+ headers: {
1816
+ "Content-Type": "application/json",
1817
+ ...observationRequestHeaders(this.observation)
1818
+ },
1735
1819
  body: JSON.stringify({
1736
1820
  email: input.email,
1737
1821
  type: "sign-in"
@@ -2105,12 +2189,14 @@ var BetterAuthNodeAdapter = class {
2105
2189
  origin;
2106
2190
  cookieJar;
2107
2191
  fetchImpl;
2192
+ observation;
2108
2193
  constructor(deps) {
2109
2194
  this.authBaseUrl = deps.authBaseUrl.replace(/\/$/, "");
2110
2195
  this.host = hostFromBaseUrl(this.authBaseUrl);
2111
2196
  this.origin = deps.origin?.replace(/\/$/, "");
2112
2197
  this.cookieJar = deps.cookieJar ?? new CookieJar();
2113
2198
  this.fetchImpl = deps.fetch ?? fetch;
2199
+ this.observation = deps.observation;
2114
2200
  }
2115
2201
  url(path) {
2116
2202
  return resolveAuthClientUrl(this.authBaseUrl, path);
@@ -2145,7 +2231,8 @@ var BetterAuthNodeAdapter = class {
2145
2231
  method: "POST",
2146
2232
  headers: {
2147
2233
  "content-type": "application/json",
2148
- ...this.origin ? { origin: this.origin } : {}
2234
+ ...this.origin ? { origin: this.origin } : {},
2235
+ ...observationRequestHeaders(this.observation)
2149
2236
  },
2150
2237
  body: JSON.stringify({
2151
2238
  email: input.email,
@@ -2757,8 +2844,10 @@ async function safeText(res) {
2757
2844
  var HttpBootstrapAdapter = class {
2758
2845
  bootstrapBaseUrl;
2759
2846
  fetchImpl;
2847
+ observation;
2760
2848
  constructor(deps) {
2761
2849
  this.bootstrapBaseUrl = deps.bootstrapBaseUrl.replace(/\/$/, "");
2850
+ this.observation = deps.observation;
2762
2851
  this.fetchImpl = deps.fetch ?? ((input, init) => globalThis.fetch(input, init));
2763
2852
  }
2764
2853
  resolve(input) {
@@ -2766,7 +2855,8 @@ var HttpBootstrapAdapter = class {
2766
2855
  try: () => {
2767
2856
  const headers = {
2768
2857
  "content-type": "application/json",
2769
- ...input.origin === void 0 ? {} : { origin: input.origin }
2858
+ ...input.origin === void 0 ? {} : { origin: input.origin },
2859
+ ...observationRequestHeaders(this.observation)
2770
2860
  };
2771
2861
  return this.fetchImpl(`${this.bootstrapBaseUrl}/v1/client/bootstrap`, {
2772
2862
  method: "POST",
@@ -2860,13 +2950,58 @@ function convexCallErrorFromCapxul(operation, error) {
2860
2950
  }
2861
2951
  var ConvexCallPortTag = class extends Context.Tag("@capxul/sdk/ports/ConvexCallPort")() {};
2862
2952
  //#endregion
2953
+ //#region src/internal/invocation-observation.ts
2954
+ const INVOCATION_OBSERVATION = Symbol("capxul.invocation-observation");
2955
+ const FAILURE_INVOCATION_SNAPSHOT = Symbol("capxul.failure-invocation-snapshot");
2956
+ /** @internal Attach one immutable, non-wire invocation snapshot to an SDK-owned object. */
2957
+ function attachInvocationObservation(target, context) {
2958
+ const snapshot = Object.freeze(context === void 0 ? {} : { context: Object.freeze({ ...context }) });
2959
+ Object.defineProperty(target, INVOCATION_OBSERVATION, {
2960
+ configurable: false,
2961
+ enumerable: false,
2962
+ value: snapshot,
2963
+ writable: false
2964
+ });
2965
+ return target;
2966
+ }
2967
+ /** @internal Read the snapshot without exposing its symbol or adding a wire field. */
2968
+ function readInvocationObservation(source) {
2969
+ if (typeof source !== "object" || source === null) return void 0;
2970
+ return source[INVOCATION_OBSERVATION];
2971
+ }
2972
+ /** @internal Carry a snapshot across an SDK adapter projection without resolving again. */
2973
+ function copyInvocationObservation(source, target) {
2974
+ const snapshot = readInvocationObservation(source);
2975
+ return snapshot === void 0 ? target : attachInvocationObservation(target, snapshot.context);
2976
+ }
2977
+ /** @internal Mark a failure envelope as already resolved at the public invocation boundary. */
2978
+ function markFailureInvocationSnapshot(failure) {
2979
+ Object.defineProperty(failure, FAILURE_INVOCATION_SNAPSHOT, {
2980
+ configurable: false,
2981
+ enumerable: false,
2982
+ value: true,
2983
+ writable: false
2984
+ });
2985
+ return failure;
2986
+ }
2987
+ /** @internal Distinguish public-boundary failures from direct adapter calls. */
2988
+ function hasFailureInvocationSnapshot(failure) {
2989
+ return typeof failure === "object" && failure !== null && failure[FAILURE_INVOCATION_SNAPSHOT] === true;
2990
+ }
2991
+ //#endregion
2863
2992
  //#region src/adapters/convex-call/ConvexCallAdapter.ts
2993
+ /** Exact floor-first allowlist; every additional handler must migrate its validator first. */
2994
+ const OBSERVED_CONVEX_ACTIONS = new Set(["subAccount/actions:transfer"]);
2864
2995
  var ConvexCallAdapter = class {
2865
2996
  #client;
2866
2997
  #tokenProvider;
2998
+ #applicationId;
2999
+ #observation;
2867
3000
  constructor(deps) {
2868
3001
  this.#client = deps.client ?? new ConvexClient(deps.convexUrl);
2869
3002
  this.#tokenProvider = deps.tokenProvider;
3003
+ this.#applicationId = deps.applicationId;
3004
+ this.#observation = deps.observation;
2870
3005
  if (this.#tokenProvider) this.#client.setAuth(this.#tokenProvider);
2871
3006
  }
2872
3007
  refreshAuth() {
@@ -2885,10 +3020,36 @@ var ConvexCallAdapter = class {
2885
3020
  });
2886
3021
  }
2887
3022
  action(fn, args) {
3023
+ const path = getFunctionName(fn);
2888
3024
  return Effect.tryPromise({
2889
- try: () => this.#client.action(fn, args),
2890
- catch: (cause) => mapToConvexCallError(getFunctionName(fn), cause)
3025
+ try: () => this.#client.action(fn, this.#observedActionArgs(path, args)),
3026
+ catch: (cause) => mapToConvexCallError(path, cause)
3027
+ });
3028
+ }
3029
+ #observedActionArgs(path, args) {
3030
+ if (!OBSERVED_CONVEX_ACTIONS.has(path)) return args;
3031
+ let hostContext;
3032
+ const invocationSnapshot = readInvocationObservation(args);
3033
+ if (invocationSnapshot !== void 0) hostContext = invocationSnapshot.context;
3034
+ else {
3035
+ const resolveContext = this.#observation?.resolveContext;
3036
+ if (resolveContext === void 0) return args;
3037
+ try {
3038
+ hostContext = resolveContext();
3039
+ } catch {
3040
+ return args;
3041
+ }
3042
+ }
3043
+ if (hostContext === void 0) return args;
3044
+ hostContext = sanitizeObservationContext({
3045
+ ...hostContext,
3046
+ ...this.#applicationId === void 0 ? {} : { applicationId: this.#applicationId }
2891
3047
  });
3048
+ if (hostContext === void 0) return args;
3049
+ return {
3050
+ ...args,
3051
+ observationContext: hostContext
3052
+ };
2892
3053
  }
2893
3054
  subscribe(fn, args, callback) {
2894
3055
  return Effect.try({
@@ -3661,12 +3822,12 @@ var ConvexSubAccountAdapter = class {
3661
3822
  const operation = "transfer";
3662
3823
  return Effect.suspend(() => {
3663
3824
  const rawAmount = toWei(input.amount);
3664
- return this.#convex.action(this.#fns.transfer, {
3825
+ return this.#convex.action(this.#fns.transfer, copyInvocationObservation(input, {
3665
3826
  chainId: this.#chainId,
3666
3827
  from: input.from,
3667
3828
  to: input.to,
3668
3829
  rawAmount
3669
- });
3830
+ }));
3670
3831
  }).pipe(Effect.mapError((error) => subAccountErrorFromCapxul(operation, error.publicError, error)), Effect.map((wire) => brandTransferResult(wire)), Effect.catchAllDefect((cause) => Effect.fail(subAccountErrorFromUnknown(operation, cause))));
3671
3832
  }
3672
3833
  #runMutation(operation, ref, args) {
@@ -3963,6 +4124,10 @@ const TransferRequestedProps = Schema.Struct({
3963
4124
  amount: OptionalWeiAmount,
3964
4125
  direction: OptionalTransferDirection
3965
4126
  });
4127
+ const TransferBackendReceivedProps = Schema.Struct({
4128
+ ...TelemetryEnvelopeProps,
4129
+ direction: OptionalTransferDirection
4130
+ });
3966
4131
  const TransferConfirmedProps = Schema.Struct({
3967
4132
  ...TelemetryEnvelopeProps,
3968
4133
  amount: OptionalWeiAmount,
@@ -4179,6 +4344,10 @@ Schema.Struct({
4179
4344
  name: Schema.Literal("transfer_requested"),
4180
4345
  props: Schema.optional(TransferRequestedProps)
4181
4346
  });
4347
+ Schema.Struct({
4348
+ name: Schema.Literal("transfer_backend_received"),
4349
+ props: Schema.optional(TransferBackendReceivedProps)
4350
+ });
4182
4351
  Schema.Struct({
4183
4352
  name: Schema.Literal("transfer_confirmed"),
4184
4353
  props: Schema.optional(TransferConfirmedProps)
@@ -7872,32 +8041,6 @@ const EXPECTED_OPERATION_OUTCOMES = new Set([
7872
8041
  "OTP_EXPIRED",
7873
8042
  "WRONG_STATE"
7874
8043
  ]);
7875
- const CONTEXT_PROPERTY_RULES = {
7876
- application: {
7877
- maxLength: 64,
7878
- pattern: /^[A-Za-z0-9][A-Za-z0-9._-]*$/u
7879
- },
7880
- release: {
7881
- maxLength: 128,
7882
- pattern: /^[A-Za-z0-9][A-Za-z0-9._+@:/-]*$/u
7883
- },
7884
- session_id: {
7885
- maxLength: 128,
7886
- pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
7887
- },
7888
- organization_id: {
7889
- maxLength: 128,
7890
- pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
7891
- },
7892
- correlation_id: {
7893
- maxLength: 128,
7894
- pattern: /^[A-Za-z0-9][A-Za-z0-9._:-]*$/u
7895
- }
7896
- };
7897
- const EMBEDDED_WALLET_MATERIAL = /0x[a-fA-F0-9]{40,}/u;
7898
- const RAW_PRIVATE_KEY_MATERIAL = /(?:^|[^a-fA-F0-9])[a-fA-F0-9]{64}(?:$|[^a-fA-F0-9])/u;
7899
- const COMPACT_JWT = /eyJ[A-Za-z0-9_-]*\.[A-Za-z0-9_-]+\.[A-Za-z0-9_-]+/u;
7900
- const KNOWN_CREDENTIAL_PREFIX = /(?:(?:sk|pk|rk)_(?:live|test)|(?:phc|phx|ghp|gho|ghu|ghs|ghr|whsec)_|github_pat_|xox[baprs]-|AKIA[0-9A-Z]{16}|AIza)[A-Za-z0-9_-]*/iu;
7901
8044
  /**
7902
8045
  * Adapt the host's already-initialized PostHog-like client. This function does
7903
8046
  * not import, initialize, configure, or own PostHog.
@@ -7907,7 +8050,7 @@ function fromPostHog(client, options = {}) {
7907
8050
  if (!isEnabled(options.enabled)) return;
7908
8051
  if (client === null || client === void 0) return;
7909
8052
  const safeFailure = sanitizeFailureObservation(failure);
7910
- return [safeFailure, postHogProperties(safeFailure, resolveContext(options.context))];
8053
+ return [safeFailure, postHogProperties(safeFailure, hasFailureInvocationSnapshot(failure) ? void 0 : resolveContext(options.context))];
7911
8054
  };
7912
8055
  const captureOperationFailure = (failure) => {
7913
8056
  const prepared = prepare(failure);
@@ -7932,6 +8075,10 @@ function fromPostHog(client, options = {}) {
7932
8075
  deliver(() => client.captureException(safeFailure.exception, properties));
7933
8076
  };
7934
8077
  return {
8078
+ resolveContext: () => {
8079
+ if (!isEnabled(options.enabled) || client === null || client === void 0) return void 0;
8080
+ return resolveContext(options.context) ?? {};
8081
+ },
7935
8082
  captureOperationFailure,
7936
8083
  captureException
7937
8084
  };
@@ -7982,18 +8129,20 @@ function observeSdkClient(client, adapter) {
7982
8129
  if (cached !== void 0) return cached;
7983
8130
  const wrapped = new Proxy(callable, {
7984
8131
  apply(currentTarget, _thisArg, args) {
8132
+ const invocationContext = resolveAdapterContext(adapter);
8133
+ const invocationArgs = carryInvocationContext(operation, args, invocationContext);
7985
8134
  let output;
7986
8135
  try {
7987
- output = Reflect.apply(currentTarget, owner, args);
8136
+ output = Reflect.apply(currentTarget, owner, invocationArgs);
7988
8137
  } catch (cause) {
7989
- report(adapter, "exception", operation, cause);
8138
+ report(adapter, "exception", operation, cause, invocationContext);
7990
8139
  throw cause;
7991
8140
  }
7992
- if (isPromiseLike(output)) return Promise.resolve(output).then((result) => processOutput(result, path), (cause) => {
7993
- report(adapter, "exception", operation, cause);
8141
+ if (isPromiseLike(output)) return Promise.resolve(output).then((result) => processOutput(result, path, invocationContext), (cause) => {
8142
+ report(adapter, "exception", operation, cause, invocationContext);
7994
8143
  throw cause;
7995
8144
  });
7996
- return processOutput(output, path);
8145
+ return processOutput(output, path, invocationContext);
7997
8146
  },
7998
8147
  get(currentTarget, property) {
7999
8148
  const attached = Reflect.get(currentTarget, property, currentTarget);
@@ -8006,9 +8155,9 @@ function observeSdkClient(client, adapter) {
8006
8155
  }
8007
8156
  return isPlainObject(value) ? wrapObject(value, path) : value;
8008
8157
  };
8009
- const processOutput = (output, path) => {
8158
+ const processOutput = (output, path, invocationContext) => {
8010
8159
  if (isFailedResult(output)) {
8011
- report(adapter, "operation", path.join("."), output.error);
8160
+ report(adapter, "operation", path.join("."), output.error, invocationContext);
8012
8161
  return output;
8013
8162
  }
8014
8163
  if (isCapxulResult(output)) return output;
@@ -8016,24 +8165,40 @@ function observeSdkClient(client, adapter) {
8016
8165
  };
8017
8166
  return wrapObject(client, []);
8018
8167
  }
8168
+ function carryInvocationContext(operation, args, context) {
8169
+ if (operation !== "subAccounts.transfer" || !isPlainObject(args[0])) return args;
8170
+ return [attachInvocationObservation({ ...args[0] }, context), ...args.slice(1)];
8171
+ }
8019
8172
  /** @internal Reports a factory-level typed failure without changing its identity. */
8020
8173
  function observeFailedResult(result, adapter, operation) {
8021
- if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error);
8174
+ if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error, resolveAdapterContext(adapter));
8022
8175
  return result;
8023
8176
  }
8024
- function report(adapter, kind, operation, cause) {
8177
+ function report(adapter, kind, operation, cause, invocationContext) {
8025
8178
  const operationName = normalizeOperation(operation);
8026
8179
  const kindName = normalizeErrorKind(errorKind(cause));
8027
- const failure = {
8180
+ const context = sanitizeObservationContext({
8181
+ ...invocationContext,
8182
+ ...isCapxulError(cause) && cause.correlationId !== void 0 ? { correlationId: cause.correlationId } : {}
8183
+ });
8184
+ const failure = markFailureInvocationSnapshot({
8028
8185
  exception: syntheticException(operationName, kindName),
8029
8186
  sdkVersion: SDK_VERSION$1,
8030
8187
  operation: operationName,
8031
- errorKind: kindName
8032
- };
8188
+ errorKind: kindName,
8189
+ ...context === void 0 ? {} : { context }
8190
+ });
8033
8191
  try {
8034
8192
  ignoreDeliveryFailure(kind === "operation" ? adapter.captureOperationFailure(failure) : adapter.captureException(failure));
8035
8193
  } catch {}
8036
8194
  }
8195
+ function resolveAdapterContext(adapter) {
8196
+ try {
8197
+ return sanitizeObservationContext(adapter.resolveContext?.());
8198
+ } catch {
8199
+ return;
8200
+ }
8201
+ }
8037
8202
  function ignoreDeliveryFailure(delivery) {
8038
8203
  if (!isPromiseLike(delivery)) return;
8039
8204
  try {
@@ -8047,25 +8212,21 @@ function postHogProperties(failure, context) {
8047
8212
  error_kind: failure.errorKind,
8048
8213
  handled: true
8049
8214
  };
8050
- assignSafeContext(properties, "application", context?.application);
8051
- assignSafeContext(properties, "release", context?.release);
8052
- assignSafeContext(properties, "session_id", context?.sessionId);
8053
- assignSafeContext(properties, "organization_id", context?.organizationId);
8054
- assignSafeContext(properties, "correlation_id", context?.correlationId);
8215
+ const merged = sanitizeObservationContext({
8216
+ ...context,
8217
+ ...failure.context
8218
+ });
8219
+ if (merged?.application !== void 0) properties.application = merged.application;
8220
+ if (merged?.release !== void 0) properties.release = merged.release;
8221
+ if (merged?.sessionId !== void 0) properties.session_id = merged.sessionId;
8222
+ if (merged?.organizationId !== void 0) properties.organization_id = merged.organizationId;
8223
+ if (merged?.correlationId !== void 0) properties.correlation_id = merged.correlationId;
8224
+ if (merged?.anonymousId !== void 0) properties.anonymous_id = merged.anonymousId;
8055
8225
  return properties;
8056
8226
  }
8057
- function assignSafeContext(properties, key, value) {
8058
- if (typeof value !== "string") return;
8059
- const rule = CONTEXT_PROPERTY_RULES[key];
8060
- if (value.length === 0 || value.length > rule.maxLength || value !== value.trim() || value.includes("://") || containsSensitiveContext(value) || !rule.pattern.test(value)) return;
8061
- properties[key] = value;
8062
- }
8063
- function containsSensitiveContext(value) {
8064
- return EMBEDDED_WALLET_MATERIAL.test(value) || RAW_PRIVATE_KEY_MATERIAL.test(value) || COMPACT_JWT.test(value) || KNOWN_CREDENTIAL_PREFIX.test(value);
8065
- }
8066
8227
  function resolveContext(context) {
8067
8228
  try {
8068
- return typeof context === "function" ? context() : context;
8229
+ return sanitizeObservationContext(typeof context === "function" ? context() : context);
8069
8230
  } catch {
8070
8231
  return;
8071
8232
  }
@@ -8089,11 +8250,13 @@ function errorKind(cause) {
8089
8250
  function sanitizeFailureObservation(failure) {
8090
8251
  const operation = normalizeOperation(failure.operation);
8091
8252
  const kind = normalizeErrorKind(failure.errorKind);
8253
+ const context = sanitizeObservationContext(failure.context);
8092
8254
  return {
8093
8255
  exception: syntheticException(operation, kind),
8094
8256
  sdkVersion: normalizeSdkVersion(failure.sdkVersion),
8095
8257
  operation,
8096
- errorKind: kind
8258
+ errorKind: kind,
8259
+ ...context === void 0 ? {} : { context }
8097
8260
  };
8098
8261
  }
8099
8262
  function normalizeSdkVersion(value) {
@@ -8232,11 +8395,13 @@ function productionBootstrapPortLayer(bootstrap) {
8232
8395
  function productionAuthClientLayer(input, refreshConvexAuthRef) {
8233
8396
  return (input.runtime === "browser" ? BetterAuthBrowserLayer({
8234
8397
  authBaseUrl: input.runtimeUrls.authBaseUrl,
8235
- ...input.fetch === void 0 ? {} : { fetch: input.fetch }
8398
+ ...input.fetch === void 0 ? {} : { fetch: input.fetch },
8399
+ ...input.observation === void 0 ? {} : { observation: input.observation }
8236
8400
  }) : BetterAuthNodeLayer({
8237
8401
  authBaseUrl: input.runtimeUrls.authBaseUrl,
8238
8402
  ...input.origin === void 0 ? {} : { origin: input.origin },
8239
- ...input.fetch === void 0 ? {} : { fetch: input.fetch }
8403
+ ...input.fetch === void 0 ? {} : { fetch: input.fetch },
8404
+ ...input.observation === void 0 ? {} : { observation: input.observation }
8240
8405
  })).pipe(Layer.map((context) => {
8241
8406
  const authClient = Context.get(context, AuthClientPortTag);
8242
8407
  return Context.make(AuthClientPortTag, refreshConvexAuthOnSession(authClient, () => {
@@ -8255,6 +8420,8 @@ function productionAuthCacheLayer(input) {
8255
8420
  function productionConvexCallLayer(input, refreshConvexAuthRef) {
8256
8421
  return Layer.unwrapEffect(Effect.map(AuthClientPortTag, (authClient) => ConvexCallLayer({
8257
8422
  convexUrl: input.runtimeUrls.convexUrl,
8423
+ ...input.applicationId === void 0 ? {} : { applicationId: input.applicationId },
8424
+ ...input.observation === void 0 ? {} : { observation: input.observation },
8258
8425
  ...input.convexClient === void 0 ? {} : { client: input.convexClient },
8259
8426
  tokenProvider: async ({ forceRefreshToken }) => {
8260
8427
  const tokenResult = await Effect.runPromise(Effect.either(authClient.getConvexJwt({
@@ -8286,7 +8453,8 @@ async function createProductionAdapters(input) {
8286
8453
  const closeScope = idempotentClose(() => Effect.runPromise(Scope.close(scope, Exit.void)));
8287
8454
  const bootstrapLayer = HttpBootstrapLayer({
8288
8455
  bootstrapBaseUrl: resolvedInput.value.bootstrapBaseUrl,
8289
- ...input.fetch === void 0 ? {} : { fetch: input.fetch }
8456
+ ...input.fetch === void 0 ? {} : { fetch: input.fetch },
8457
+ ...input.observation === void 0 ? {} : { observation: input.observation }
8290
8458
  });
8291
8459
  try {
8292
8460
  const bootstrapContext = await Effect.runPromise(Layer.buildWithScope(bootstrapLayer, scope));
@@ -8344,6 +8512,8 @@ async function createProductionAdapters(input) {
8344
8512
  ...resolvedInput.value.origin === void 0 ? {} : { origin: resolvedInput.value.origin },
8345
8513
  runtimeUrls: runtimeUrls.value,
8346
8514
  chainId: bootstrapResult.value.chainId,
8515
+ applicationId: bootstrapResult.value.applicationId,
8516
+ ...input.observation === void 0 ? {} : { observation: input.observation },
8347
8517
  ...input.authCache === void 0 ? {} : { authCache: input.authCache },
8348
8518
  ...input.telemetry === void 0 ? {} : { telemetry: input.telemetry },
8349
8519
  ...injectedClient === void 0 ? {} : { convexClient: injectedClient },