@capxul/sdk 1.0.0-alpha.15 → 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/README.md +1 -0
- package/dist/index.d.mts +75 -2
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +461 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +6 -4
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.
|
|
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") {};
|
|
@@ -1627,11 +1627,11 @@ function fromResult(operation, run) {
|
|
|
1627
1627
|
})
|
|
1628
1628
|
}).pipe(Effect.flatMap((result) => result.ok ? Effect.succeed(result.value) : Effect.fail(new AuthClientError({
|
|
1629
1629
|
operation,
|
|
1630
|
-
kind: errorKind(result.error),
|
|
1630
|
+
kind: errorKind$1(result.error),
|
|
1631
1631
|
cause: result.error
|
|
1632
1632
|
}))));
|
|
1633
1633
|
}
|
|
1634
|
-
function errorKind(error) {
|
|
1634
|
+
function errorKind$1(error) {
|
|
1635
1635
|
if (error.code === "CANCELLED") return "cancelled";
|
|
1636
1636
|
if (error.code === "NETWORK_ERROR") return "network";
|
|
1637
1637
|
if (error.code === "INVALID_INPUT" || error.code === "OTP_EXPIRED") return "validation";
|
|
@@ -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: {
|
|
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,11 +3020,37 @@ 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(
|
|
3025
|
+
try: () => this.#client.action(fn, this.#observedActionArgs(path, args)),
|
|
3026
|
+
catch: (cause) => mapToConvexCallError(path, cause)
|
|
2891
3027
|
});
|
|
2892
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 }
|
|
3047
|
+
});
|
|
3048
|
+
if (hostContext === void 0) return args;
|
|
3049
|
+
return {
|
|
3050
|
+
...args,
|
|
3051
|
+
observationContext: hostContext
|
|
3052
|
+
};
|
|
3053
|
+
}
|
|
2893
3054
|
subscribe(fn, args, callback) {
|
|
2894
3055
|
return Effect.try({
|
|
2895
3056
|
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)
|
|
@@ -7854,6 +8023,271 @@ function assembleCapxulClient(input) {
|
|
|
7854
8023
|
}
|
|
7855
8024
|
};
|
|
7856
8025
|
}
|
|
8026
|
+
//#endregion
|
|
8027
|
+
//#region src/observation.ts
|
|
8028
|
+
const SDK_VERSION$1 = version;
|
|
8029
|
+
/** Stable PostHog event used for typed failures that are expected product outcomes. */
|
|
8030
|
+
const CAPXUL_SDK_EXPECTED_OUTCOME_EVENT = "capxul_sdk_expected_outcome";
|
|
8031
|
+
const EXPECTED_OPERATION_OUTCOMES = new Set([
|
|
8032
|
+
"INVALID_INPUT",
|
|
8033
|
+
"NOT_AUTHENTICATED",
|
|
8034
|
+
"CANCELLED",
|
|
8035
|
+
"SIGNER_REJECTED",
|
|
8036
|
+
"VERIFICATION_REQUIRED",
|
|
8037
|
+
"INSUFFICIENT_BALANCE",
|
|
8038
|
+
"INVALID_RECIPIENT",
|
|
8039
|
+
"ROLE_PERMISSION_DENIED",
|
|
8040
|
+
"RATE_LIMITED",
|
|
8041
|
+
"OTP_EXPIRED",
|
|
8042
|
+
"WRONG_STATE"
|
|
8043
|
+
]);
|
|
8044
|
+
/**
|
|
8045
|
+
* Adapt the host's already-initialized PostHog-like client. This function does
|
|
8046
|
+
* not import, initialize, configure, or own PostHog.
|
|
8047
|
+
*/
|
|
8048
|
+
function fromPostHog(client, options = {}) {
|
|
8049
|
+
const prepare = (failure) => {
|
|
8050
|
+
if (!isEnabled(options.enabled)) return;
|
|
8051
|
+
if (client === null || client === void 0) return;
|
|
8052
|
+
const safeFailure = sanitizeFailureObservation(failure);
|
|
8053
|
+
return [safeFailure, postHogProperties(safeFailure, hasFailureInvocationSnapshot(failure) ? void 0 : resolveContext(options.context))];
|
|
8054
|
+
};
|
|
8055
|
+
const captureOperationFailure = (failure) => {
|
|
8056
|
+
const prepared = prepare(failure);
|
|
8057
|
+
if (prepared === void 0 || client === null || client === void 0) return;
|
|
8058
|
+
const [safeFailure, properties] = prepared;
|
|
8059
|
+
if (classifyOperationOutcome(safeFailure.errorKind) === "expected") {
|
|
8060
|
+
if (typeof client.capture !== "function") return;
|
|
8061
|
+
deliver(() => client.capture(CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, {
|
|
8062
|
+
...properties,
|
|
8063
|
+
outcome_class: "expected"
|
|
8064
|
+
}));
|
|
8065
|
+
return;
|
|
8066
|
+
}
|
|
8067
|
+
if (typeof client.captureException !== "function") return;
|
|
8068
|
+
deliver(() => client.captureException(safeFailure.exception, properties));
|
|
8069
|
+
};
|
|
8070
|
+
const captureException = (failure) => {
|
|
8071
|
+
const prepared = prepare(failure);
|
|
8072
|
+
if (prepared === void 0 || client === null || client === void 0) return;
|
|
8073
|
+
if (typeof client.captureException !== "function") return;
|
|
8074
|
+
const [safeFailure, properties] = prepared;
|
|
8075
|
+
deliver(() => client.captureException(safeFailure.exception, properties));
|
|
8076
|
+
};
|
|
8077
|
+
return {
|
|
8078
|
+
resolveContext: () => {
|
|
8079
|
+
if (!isEnabled(options.enabled) || client === null || client === void 0) return void 0;
|
|
8080
|
+
return resolveContext(options.context) ?? {};
|
|
8081
|
+
},
|
|
8082
|
+
captureOperationFailure,
|
|
8083
|
+
captureException
|
|
8084
|
+
};
|
|
8085
|
+
}
|
|
8086
|
+
function classifyOperationOutcome(kind) {
|
|
8087
|
+
return EXPECTED_OPERATION_OUTCOMES.has(kind) ? "expected" : "unexpected";
|
|
8088
|
+
}
|
|
8089
|
+
function deliver(capture) {
|
|
8090
|
+
try {
|
|
8091
|
+
ignoreDeliveryFailure(capture());
|
|
8092
|
+
} catch {}
|
|
8093
|
+
}
|
|
8094
|
+
/** @internal Decorates public client method bundles at the owning SDK boundary. */
|
|
8095
|
+
function observeSdkClient(client, adapter) {
|
|
8096
|
+
if (adapter === void 0) return client;
|
|
8097
|
+
const objectProxies = /* @__PURE__ */ new WeakMap();
|
|
8098
|
+
const functionWrappers = /* @__PURE__ */ new WeakMap();
|
|
8099
|
+
const wrapObject = (target, path, internal = false) => {
|
|
8100
|
+
const cacheKey = `${internal ? "internal" : "public"}:${path.join(".")}`;
|
|
8101
|
+
let targetProxies = objectProxies.get(target);
|
|
8102
|
+
const cached = targetProxies?.get(cacheKey);
|
|
8103
|
+
if (cached !== void 0) return cached;
|
|
8104
|
+
const proxy = new Proxy(target, { get(currentTarget, property, receiver) {
|
|
8105
|
+
const value = Reflect.get(currentTarget, property, receiver);
|
|
8106
|
+
if (typeof property !== "string") return value;
|
|
8107
|
+
if (path.length === 0 && property === "_internal" && isPlainObject(value)) return wrapInternal(value);
|
|
8108
|
+
if (internal && property !== "accounts") return value;
|
|
8109
|
+
return wrapValue(value, [...path, property], currentTarget);
|
|
8110
|
+
} });
|
|
8111
|
+
if (targetProxies === void 0) {
|
|
8112
|
+
targetProxies = /* @__PURE__ */ new Map();
|
|
8113
|
+
objectProxies.set(target, targetProxies);
|
|
8114
|
+
}
|
|
8115
|
+
targetProxies.set(cacheKey, proxy);
|
|
8116
|
+
return proxy;
|
|
8117
|
+
};
|
|
8118
|
+
const wrapInternal = (target) => wrapObject(target, ["_internal"], true);
|
|
8119
|
+
const wrapValue = (value, path, owner) => {
|
|
8120
|
+
if (typeof value === "function") {
|
|
8121
|
+
const callable = value;
|
|
8122
|
+
const operation = path.join(".");
|
|
8123
|
+
let ownerWrappers = functionWrappers.get(owner);
|
|
8124
|
+
if (ownerWrappers === void 0) {
|
|
8125
|
+
ownerWrappers = /* @__PURE__ */ new Map();
|
|
8126
|
+
functionWrappers.set(owner, ownerWrappers);
|
|
8127
|
+
}
|
|
8128
|
+
const cached = ownerWrappers.get(operation);
|
|
8129
|
+
if (cached !== void 0) return cached;
|
|
8130
|
+
const wrapped = new Proxy(callable, {
|
|
8131
|
+
apply(currentTarget, _thisArg, args) {
|
|
8132
|
+
const invocationContext = resolveAdapterContext(adapter);
|
|
8133
|
+
const invocationArgs = carryInvocationContext(operation, args, invocationContext);
|
|
8134
|
+
let output;
|
|
8135
|
+
try {
|
|
8136
|
+
output = Reflect.apply(currentTarget, owner, invocationArgs);
|
|
8137
|
+
} catch (cause) {
|
|
8138
|
+
report(adapter, "exception", operation, cause, invocationContext);
|
|
8139
|
+
throw cause;
|
|
8140
|
+
}
|
|
8141
|
+
if (isPromiseLike(output)) return Promise.resolve(output).then((result) => processOutput(result, path, invocationContext), (cause) => {
|
|
8142
|
+
report(adapter, "exception", operation, cause, invocationContext);
|
|
8143
|
+
throw cause;
|
|
8144
|
+
});
|
|
8145
|
+
return processOutput(output, path, invocationContext);
|
|
8146
|
+
},
|
|
8147
|
+
get(currentTarget, property) {
|
|
8148
|
+
const attached = Reflect.get(currentTarget, property, currentTarget);
|
|
8149
|
+
if (typeof property !== "string") return attached;
|
|
8150
|
+
return wrapValue(attached, [...path, property], currentTarget);
|
|
8151
|
+
}
|
|
8152
|
+
});
|
|
8153
|
+
ownerWrappers.set(operation, wrapped);
|
|
8154
|
+
return wrapped;
|
|
8155
|
+
}
|
|
8156
|
+
return isPlainObject(value) ? wrapObject(value, path) : value;
|
|
8157
|
+
};
|
|
8158
|
+
const processOutput = (output, path, invocationContext) => {
|
|
8159
|
+
if (isFailedResult(output)) {
|
|
8160
|
+
report(adapter, "operation", path.join("."), output.error, invocationContext);
|
|
8161
|
+
return output;
|
|
8162
|
+
}
|
|
8163
|
+
if (isCapxulResult(output)) return output;
|
|
8164
|
+
return isPlainObject(output) ? wrapObject(output, path) : output;
|
|
8165
|
+
};
|
|
8166
|
+
return wrapObject(client, []);
|
|
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
|
+
}
|
|
8172
|
+
/** @internal Reports a factory-level typed failure without changing its identity. */
|
|
8173
|
+
function observeFailedResult(result, adapter, operation) {
|
|
8174
|
+
if (adapter !== void 0 && isFailedResult(result)) report(adapter, "operation", operation, result.error, resolveAdapterContext(adapter));
|
|
8175
|
+
return result;
|
|
8176
|
+
}
|
|
8177
|
+
function report(adapter, kind, operation, cause, invocationContext) {
|
|
8178
|
+
const operationName = normalizeOperation(operation);
|
|
8179
|
+
const kindName = normalizeErrorKind(errorKind(cause));
|
|
8180
|
+
const context = sanitizeObservationContext({
|
|
8181
|
+
...invocationContext,
|
|
8182
|
+
...isCapxulError(cause) && cause.correlationId !== void 0 ? { correlationId: cause.correlationId } : {}
|
|
8183
|
+
});
|
|
8184
|
+
const failure = markFailureInvocationSnapshot({
|
|
8185
|
+
exception: syntheticException(operationName, kindName),
|
|
8186
|
+
sdkVersion: SDK_VERSION$1,
|
|
8187
|
+
operation: operationName,
|
|
8188
|
+
errorKind: kindName,
|
|
8189
|
+
...context === void 0 ? {} : { context }
|
|
8190
|
+
});
|
|
8191
|
+
try {
|
|
8192
|
+
ignoreDeliveryFailure(kind === "operation" ? adapter.captureOperationFailure(failure) : adapter.captureException(failure));
|
|
8193
|
+
} catch {}
|
|
8194
|
+
}
|
|
8195
|
+
function resolveAdapterContext(adapter) {
|
|
8196
|
+
try {
|
|
8197
|
+
return sanitizeObservationContext(adapter.resolveContext?.());
|
|
8198
|
+
} catch {
|
|
8199
|
+
return;
|
|
8200
|
+
}
|
|
8201
|
+
}
|
|
8202
|
+
function ignoreDeliveryFailure(delivery) {
|
|
8203
|
+
if (!isPromiseLike(delivery)) return;
|
|
8204
|
+
try {
|
|
8205
|
+
Promise.resolve(delivery).catch(() => void 0);
|
|
8206
|
+
} catch {}
|
|
8207
|
+
}
|
|
8208
|
+
function postHogProperties(failure, context) {
|
|
8209
|
+
const properties = {
|
|
8210
|
+
sdk_version: failure.sdkVersion,
|
|
8211
|
+
operation: failure.operation,
|
|
8212
|
+
error_kind: failure.errorKind,
|
|
8213
|
+
handled: true
|
|
8214
|
+
};
|
|
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;
|
|
8225
|
+
return properties;
|
|
8226
|
+
}
|
|
8227
|
+
function resolveContext(context) {
|
|
8228
|
+
try {
|
|
8229
|
+
return sanitizeObservationContext(typeof context === "function" ? context() : context);
|
|
8230
|
+
} catch {
|
|
8231
|
+
return;
|
|
8232
|
+
}
|
|
8233
|
+
}
|
|
8234
|
+
function isEnabled(enabled) {
|
|
8235
|
+
try {
|
|
8236
|
+
return typeof enabled === "function" ? enabled() : enabled ?? true;
|
|
8237
|
+
} catch {
|
|
8238
|
+
return false;
|
|
8239
|
+
}
|
|
8240
|
+
}
|
|
8241
|
+
function errorKind(cause) {
|
|
8242
|
+
try {
|
|
8243
|
+
if (isCapxulError(cause)) return normalizeErrorKind(cause.code);
|
|
8244
|
+
if (cause instanceof Error) return normalizeErrorKind(cause.name);
|
|
8245
|
+
return "UnknownFailure";
|
|
8246
|
+
} catch {
|
|
8247
|
+
return "Error";
|
|
8248
|
+
}
|
|
8249
|
+
}
|
|
8250
|
+
function sanitizeFailureObservation(failure) {
|
|
8251
|
+
const operation = normalizeOperation(failure.operation);
|
|
8252
|
+
const kind = normalizeErrorKind(failure.errorKind);
|
|
8253
|
+
const context = sanitizeObservationContext(failure.context);
|
|
8254
|
+
return {
|
|
8255
|
+
exception: syntheticException(operation, kind),
|
|
8256
|
+
sdkVersion: normalizeSdkVersion(failure.sdkVersion),
|
|
8257
|
+
operation,
|
|
8258
|
+
errorKind: kind,
|
|
8259
|
+
...context === void 0 ? {} : { context }
|
|
8260
|
+
};
|
|
8261
|
+
}
|
|
8262
|
+
function normalizeSdkVersion(value) {
|
|
8263
|
+
return typeof value === "string" && /^[A-Za-z0-9][A-Za-z0-9.+_-]{0,127}$/u.test(value) ? value : "unknown";
|
|
8264
|
+
}
|
|
8265
|
+
function normalizeOperation(value) {
|
|
8266
|
+
return typeof value === "string" && /^[A-Za-z0-9_][A-Za-z0-9_.-]{0,255}$/u.test(value) ? value : "unknown";
|
|
8267
|
+
}
|
|
8268
|
+
function normalizeErrorKind(value) {
|
|
8269
|
+
return typeof value === "string" && /^[A-Za-z][A-Za-z0-9_.-]{0,63}$/u.test(value) ? value : "Error";
|
|
8270
|
+
}
|
|
8271
|
+
function syntheticException(operation, kind) {
|
|
8272
|
+
const error = /* @__PURE__ */ new Error("Capxul SDK operation failed");
|
|
8273
|
+
error.name = kind;
|
|
8274
|
+
error.stack = `${kind}: ${error.message}\n at CapxulSdkBoundary.${operation} (capxul-sdk-observation://boundary/${operation}:1:1)`;
|
|
8275
|
+
return error;
|
|
8276
|
+
}
|
|
8277
|
+
function isPromiseLike(value) {
|
|
8278
|
+
return (typeof value === "object" || typeof value === "function") && value !== null && typeof value.then === "function";
|
|
8279
|
+
}
|
|
8280
|
+
function isPlainObject(value) {
|
|
8281
|
+
if (typeof value !== "object" || value === null) return false;
|
|
8282
|
+
const prototype = Object.getPrototypeOf(value);
|
|
8283
|
+
return prototype === Object.prototype || prototype === null;
|
|
8284
|
+
}
|
|
8285
|
+
function isCapxulResult(value) {
|
|
8286
|
+
return isPlainObject(value) && typeof value.ok === "boolean";
|
|
8287
|
+
}
|
|
8288
|
+
function isFailedResult(value) {
|
|
8289
|
+
return isCapxulResult(value) && value.ok === false && "error" in value;
|
|
8290
|
+
}
|
|
7857
8291
|
const SDK_VERSION = version;
|
|
7858
8292
|
const collectProductionFlowPorts = Effect.gen(function* () {
|
|
7859
8293
|
const authClient = yield* AuthClientPortTag;
|
|
@@ -7961,11 +8395,13 @@ function productionBootstrapPortLayer(bootstrap) {
|
|
|
7961
8395
|
function productionAuthClientLayer(input, refreshConvexAuthRef) {
|
|
7962
8396
|
return (input.runtime === "browser" ? BetterAuthBrowserLayer({
|
|
7963
8397
|
authBaseUrl: input.runtimeUrls.authBaseUrl,
|
|
7964
|
-
...input.fetch === void 0 ? {} : { fetch: input.fetch }
|
|
8398
|
+
...input.fetch === void 0 ? {} : { fetch: input.fetch },
|
|
8399
|
+
...input.observation === void 0 ? {} : { observation: input.observation }
|
|
7965
8400
|
}) : BetterAuthNodeLayer({
|
|
7966
8401
|
authBaseUrl: input.runtimeUrls.authBaseUrl,
|
|
7967
8402
|
...input.origin === void 0 ? {} : { origin: input.origin },
|
|
7968
|
-
...input.fetch === void 0 ? {} : { fetch: input.fetch }
|
|
8403
|
+
...input.fetch === void 0 ? {} : { fetch: input.fetch },
|
|
8404
|
+
...input.observation === void 0 ? {} : { observation: input.observation }
|
|
7969
8405
|
})).pipe(Layer.map((context) => {
|
|
7970
8406
|
const authClient = Context.get(context, AuthClientPortTag);
|
|
7971
8407
|
return Context.make(AuthClientPortTag, refreshConvexAuthOnSession(authClient, () => {
|
|
@@ -7984,6 +8420,8 @@ function productionAuthCacheLayer(input) {
|
|
|
7984
8420
|
function productionConvexCallLayer(input, refreshConvexAuthRef) {
|
|
7985
8421
|
return Layer.unwrapEffect(Effect.map(AuthClientPortTag, (authClient) => ConvexCallLayer({
|
|
7986
8422
|
convexUrl: input.runtimeUrls.convexUrl,
|
|
8423
|
+
...input.applicationId === void 0 ? {} : { applicationId: input.applicationId },
|
|
8424
|
+
...input.observation === void 0 ? {} : { observation: input.observation },
|
|
7987
8425
|
...input.convexClient === void 0 ? {} : { client: input.convexClient },
|
|
7988
8426
|
tokenProvider: async ({ forceRefreshToken }) => {
|
|
7989
8427
|
const tokenResult = await Effect.runPromise(Effect.either(authClient.getConvexJwt({
|
|
@@ -8015,7 +8453,8 @@ async function createProductionAdapters(input) {
|
|
|
8015
8453
|
const closeScope = idempotentClose(() => Effect.runPromise(Scope.close(scope, Exit.void)));
|
|
8016
8454
|
const bootstrapLayer = HttpBootstrapLayer({
|
|
8017
8455
|
bootstrapBaseUrl: resolvedInput.value.bootstrapBaseUrl,
|
|
8018
|
-
...input.fetch === void 0 ? {} : { fetch: input.fetch }
|
|
8456
|
+
...input.fetch === void 0 ? {} : { fetch: input.fetch },
|
|
8457
|
+
...input.observation === void 0 ? {} : { observation: input.observation }
|
|
8019
8458
|
});
|
|
8020
8459
|
try {
|
|
8021
8460
|
const bootstrapContext = await Effect.runPromise(Layer.buildWithScope(bootstrapLayer, scope));
|
|
@@ -8073,6 +8512,8 @@ async function createProductionAdapters(input) {
|
|
|
8073
8512
|
...resolvedInput.value.origin === void 0 ? {} : { origin: resolvedInput.value.origin },
|
|
8074
8513
|
runtimeUrls: runtimeUrls.value,
|
|
8075
8514
|
chainId: bootstrapResult.value.chainId,
|
|
8515
|
+
applicationId: bootstrapResult.value.applicationId,
|
|
8516
|
+
...input.observation === void 0 ? {} : { observation: input.observation },
|
|
8076
8517
|
...input.authCache === void 0 ? {} : { authCache: input.authCache },
|
|
8077
8518
|
...input.telemetry === void 0 ? {} : { telemetry: input.telemetry },
|
|
8078
8519
|
...injectedClient === void 0 ? {} : { convexClient: injectedClient },
|
|
@@ -8123,9 +8564,9 @@ function wireOpenfortSignerLifecycle(client, signer) {
|
|
|
8123
8564
|
}
|
|
8124
8565
|
async function createCapxulClient$1(input) {
|
|
8125
8566
|
const validation = validateCreateCapxulClientInput(input);
|
|
8126
|
-
if (!validation.ok) return validation;
|
|
8567
|
+
if (!validation.ok) return observeFailedResult(validation, input.observation, "createCapxulClient");
|
|
8127
8568
|
const adapters = await createProductionAdapters(input);
|
|
8128
|
-
if (!adapters.ok) return adapters;
|
|
8569
|
+
if (!adapters.ok) return observeFailedResult(adapters, input.observation, "createCapxulClient");
|
|
8129
8570
|
try {
|
|
8130
8571
|
const runtime = input.runtime ?? detectRuntime();
|
|
8131
8572
|
const resolvedAuthBaseUrl = resolveBrowserAuthBaseUrl({
|
|
@@ -8151,7 +8592,7 @@ async function createCapxulClient$1(input) {
|
|
|
8151
8592
|
const upstreamClose = adapters.value.close;
|
|
8152
8593
|
return {
|
|
8153
8594
|
ok: true,
|
|
8154
|
-
value: {
|
|
8595
|
+
value: observeSdkClient({
|
|
8155
8596
|
...client,
|
|
8156
8597
|
_internal: {
|
|
8157
8598
|
...client._internal,
|
|
@@ -8160,14 +8601,14 @@ async function createCapxulClient$1(input) {
|
|
|
8160
8601
|
await upstreamClose();
|
|
8161
8602
|
}
|
|
8162
8603
|
}
|
|
8163
|
-
}
|
|
8604
|
+
}, input.observation)
|
|
8164
8605
|
};
|
|
8165
8606
|
} catch (cause) {
|
|
8166
8607
|
await adapters.value.close().catch(() => void 0);
|
|
8167
|
-
return {
|
|
8608
|
+
return observeFailedResult({
|
|
8168
8609
|
ok: false,
|
|
8169
8610
|
error: toPublicError(cause, "createCapxulClient")
|
|
8170
|
-
};
|
|
8611
|
+
}, input.observation, "createCapxulClient");
|
|
8171
8612
|
}
|
|
8172
8613
|
}
|
|
8173
8614
|
function validateCreateCapxulClientInput(input) {
|
|
@@ -8309,6 +8750,6 @@ async function createCapxulClient(input) {
|
|
|
8309
8750
|
return createCapxulClient$1(input);
|
|
8310
8751
|
}
|
|
8311
8752
|
//#endregion
|
|
8312
|
-
export { CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort };
|
|
8753
|
+
export { CAPXUL_SDK_EXPECTED_OUTCOME_EVENT, CapxulError, captureException, captureExceptionSync, createCapxulClient, deriveDevPrivateKey, devPrivateKeySigner, eip1193AccountProvider, embeddedSigner, fromPostHog, injectedWalletSigner, isCapxulError, isSettingUpLifecycle, localPrivateKeyAccountProvider, openfortEmbeddedSigner, openfortEmbeddedSignerFromWallet, openfortEmbeddedWalletPort };
|
|
8313
8754
|
|
|
8314
8755
|
//# sourceMappingURL=index.mjs.map
|