@capxul/sdk 0.1.0-alpha.6 → 0.1.0-alpha.9
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/CHANGELOG.md +15 -8
- package/README.md +86 -4
- package/dist/{client-ChfXWMzO.d.ts → client-ChZrdf3R.d.ts} +209 -15
- package/dist/{client-DW_fW9DC.d.cts → client-DG6ODWu6.d.cts} +209 -15
- package/dist/client.cjs +634 -36
- package/dist/client.d.cts +2 -3
- package/dist/client.d.ts +2 -3
- package/dist/client.js +634 -36
- package/dist/index.cjs +635 -36
- package/dist/index.d.cts +11 -33
- package/dist/index.d.ts +11 -33
- package/dist/index.js +635 -37
- package/dist/types-PM4AQRLP.d.ts +1136 -0
- package/dist/types-hfcOE7Oi.d.cts +1136 -0
- package/dist/webhooks.d.cts +1 -2
- package/dist/webhooks.d.ts +1 -2
- package/package.json +7 -7
- package/dist/types-CYvLP5pP.d.ts +0 -213
- package/dist/types-X02RbQ2u.d.cts +0 -213
package/dist/index.js
CHANGED
|
@@ -677,7 +677,12 @@ var Errors = {
|
|
|
677
677
|
"Idempotency key was already used for a different request",
|
|
678
678
|
{ details }
|
|
679
679
|
),
|
|
680
|
-
emailDeliveryFailed: (detail) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}
|
|
680
|
+
emailDeliveryFailed: (detail, details) => new CapxulError2("EMAIL_DELIVERY_FAILED", `Failed to send email: ${detail}`, {
|
|
681
|
+
details
|
|
682
|
+
}),
|
|
683
|
+
rateLimited: (details) => new CapxulError2("RATE_LIMITED", "Request was rate limited", {
|
|
684
|
+
details: { ...details }
|
|
685
|
+
}),
|
|
681
686
|
internalError: (reason) => new CapxulError2("INTERNAL_ERROR", `Internal error: ${reason}`),
|
|
682
687
|
/**
|
|
683
688
|
* Verification gate. Surfaced when a request hits a verification
|
|
@@ -750,13 +755,13 @@ function createLifecycle(initial) {
|
|
|
750
755
|
}
|
|
751
756
|
function makeBuildTimeUrlsTransport(config) {
|
|
752
757
|
if (!config.authBaseUrl || config.authBaseUrl.trim().length === 0) {
|
|
753
|
-
throw
|
|
758
|
+
throw invalidConfigError(
|
|
754
759
|
"authBaseUrl",
|
|
755
760
|
"build-time-urls transport requires a non-empty authBaseUrl."
|
|
756
761
|
);
|
|
757
762
|
}
|
|
758
763
|
if (!config.convexUrl || config.convexUrl.trim().length === 0) {
|
|
759
|
-
throw
|
|
764
|
+
throw invalidConfigError(
|
|
760
765
|
"convexUrl",
|
|
761
766
|
"build-time-urls transport requires a non-empty convexUrl."
|
|
762
767
|
);
|
|
@@ -770,6 +775,7 @@ function makeBuildTimeUrlsTransport(config) {
|
|
|
770
775
|
return {
|
|
771
776
|
authBaseUrl,
|
|
772
777
|
convexUrl,
|
|
778
|
+
ensureRuntime: async () => runtime,
|
|
773
779
|
fetch: (path, init) => fetchImpl(resolveUrl(authBaseUrl, path), init),
|
|
774
780
|
getState: lifecycle.getState,
|
|
775
781
|
subscribe: lifecycle.subscribe,
|
|
@@ -785,14 +791,15 @@ function makeBuildTimeUrlsTransport(config) {
|
|
|
785
791
|
};
|
|
786
792
|
}
|
|
787
793
|
function makePublishableKeyTransport(config) {
|
|
788
|
-
|
|
789
|
-
|
|
794
|
+
const publishableKey = config.publishableKey?.trim();
|
|
795
|
+
if (!publishableKey) {
|
|
796
|
+
throw invalidConfigError(
|
|
790
797
|
"publishableKey",
|
|
791
798
|
"publishable-key transport requires a non-empty publishableKey."
|
|
792
799
|
);
|
|
793
800
|
}
|
|
794
801
|
const fetchImpl = config.fetchImpl ?? globalThis.fetch;
|
|
795
|
-
const bootstrapUrl =
|
|
802
|
+
const bootstrapUrl = normalizeBootstrapUrl(
|
|
796
803
|
config.bootstrapUrl ?? `${CAPXUL_API_BASE_URL}/v1/client/bootstrap`
|
|
797
804
|
);
|
|
798
805
|
let authBaseUrl = "";
|
|
@@ -807,23 +814,20 @@ function makePublishableKeyTransport(config) {
|
|
|
807
814
|
const response = await fetchImpl(bootstrapUrl, {
|
|
808
815
|
method: "POST",
|
|
809
816
|
headers: { "content-type": "application/json" },
|
|
810
|
-
body: JSON.stringify({ publishableKey
|
|
817
|
+
body: JSON.stringify({ publishableKey })
|
|
811
818
|
});
|
|
812
819
|
if (!response.ok) {
|
|
813
|
-
throw
|
|
814
|
-
"publishableKey",
|
|
815
|
-
`${bootstrapUrl} failed with HTTP ${response.status}.`
|
|
816
|
-
);
|
|
820
|
+
throw await bootstrapResponseError(response, bootstrapUrl);
|
|
817
821
|
}
|
|
818
|
-
const body = await response
|
|
822
|
+
const body = await readBootstrapSuccessBody(response);
|
|
819
823
|
if (typeof body.authBaseUrl !== "string" || body.authBaseUrl.trim().length === 0) {
|
|
820
|
-
throw
|
|
824
|
+
throw bootstrapContractError(
|
|
821
825
|
"authBaseUrl",
|
|
822
826
|
"/v1/client/bootstrap returned no authBaseUrl."
|
|
823
827
|
);
|
|
824
828
|
}
|
|
825
829
|
if (typeof body.convexUrl !== "string" || body.convexUrl.trim().length === 0) {
|
|
826
|
-
throw
|
|
830
|
+
throw bootstrapContractError(
|
|
827
831
|
"convexUrl",
|
|
828
832
|
"/v1/client/bootstrap returned no convexUrl."
|
|
829
833
|
);
|
|
@@ -835,16 +839,13 @@ function makePublishableKeyTransport(config) {
|
|
|
835
839
|
return runtime;
|
|
836
840
|
})();
|
|
837
841
|
bootstrapPromise = attempt.catch((err) => {
|
|
842
|
+
const error = normalizeBootstrapThrownError(err);
|
|
838
843
|
bootstrapPromise = null;
|
|
839
844
|
lifecycle.setState({
|
|
840
845
|
status: "error",
|
|
841
|
-
error
|
|
842
|
-
code: "UNKNOWN",
|
|
843
|
-
message: "Bootstrap failed without a typed CapxulError.",
|
|
844
|
-
cause: err
|
|
845
|
-
})
|
|
846
|
+
error
|
|
846
847
|
});
|
|
847
|
-
throw
|
|
848
|
+
throw error;
|
|
848
849
|
});
|
|
849
850
|
return await bootstrapPromise;
|
|
850
851
|
}
|
|
@@ -855,6 +856,7 @@ function makePublishableKeyTransport(config) {
|
|
|
855
856
|
get convexUrl() {
|
|
856
857
|
return convexUrl;
|
|
857
858
|
},
|
|
859
|
+
ensureRuntime: ensureBootstrap,
|
|
858
860
|
fetch: async (path, init) => {
|
|
859
861
|
const resolved = await ensureBootstrap();
|
|
860
862
|
return await fetchImpl(resolveUrl(resolved.authBaseUrl, path), init);
|
|
@@ -865,7 +867,7 @@ function makePublishableKeyTransport(config) {
|
|
|
865
867
|
markAuthenticated: ({ dataClient: nextDataClient }) => {
|
|
866
868
|
const current = lifecycle.getState();
|
|
867
869
|
if (current.status !== "ready" && current.status !== "authenticated") {
|
|
868
|
-
throw
|
|
870
|
+
throw internalTransportError(
|
|
869
871
|
`markAuthenticated() called from status="${current.status}". Expected "ready" or "authenticated".`
|
|
870
872
|
);
|
|
871
873
|
}
|
|
@@ -887,6 +889,24 @@ function makePublishableKeyTransport(config) {
|
|
|
887
889
|
function stripTrailingSlash(url) {
|
|
888
890
|
return url.replace(/\/+$/, "");
|
|
889
891
|
}
|
|
892
|
+
function normalizeBootstrapUrl(url) {
|
|
893
|
+
const normalized = stripTrailingSlash(url.trim());
|
|
894
|
+
if (!isAbsoluteHttpUrl(normalized)) {
|
|
895
|
+
throw invalidConfigError(
|
|
896
|
+
"bootstrapUrl",
|
|
897
|
+
"publishable-key transport requires an absolute http(s) bootstrapUrl."
|
|
898
|
+
);
|
|
899
|
+
}
|
|
900
|
+
return normalized;
|
|
901
|
+
}
|
|
902
|
+
function isAbsoluteHttpUrl(url) {
|
|
903
|
+
try {
|
|
904
|
+
const parsed = new URL(url);
|
|
905
|
+
return parsed.protocol === "http:" || parsed.protocol === "https:";
|
|
906
|
+
} catch {
|
|
907
|
+
return false;
|
|
908
|
+
}
|
|
909
|
+
}
|
|
890
910
|
function resolveUrl(authBaseUrl, path) {
|
|
891
911
|
if (path.startsWith("http://") || path.startsWith("https://")) {
|
|
892
912
|
return path;
|
|
@@ -894,10 +914,142 @@ function resolveUrl(authBaseUrl, path) {
|
|
|
894
914
|
return `${authBaseUrl}${path}`;
|
|
895
915
|
}
|
|
896
916
|
function assertNever(value) {
|
|
897
|
-
throw
|
|
917
|
+
throw internalTransportError(
|
|
898
918
|
`Unhandled BrowserCapxulConfig.mode: ${String(value.mode)}.`
|
|
899
919
|
);
|
|
900
920
|
}
|
|
921
|
+
function invalidConfigError(field, reason) {
|
|
922
|
+
return new CapxulError({
|
|
923
|
+
code: "INVALID_INPUT",
|
|
924
|
+
message: `Invalid ${field}: ${reason}`,
|
|
925
|
+
details: { source: "sdk-config", field, reason }
|
|
926
|
+
});
|
|
927
|
+
}
|
|
928
|
+
function bootstrapContractError(field, message) {
|
|
929
|
+
return new CapxulError({
|
|
930
|
+
code: "INVALID_INPUT",
|
|
931
|
+
message,
|
|
932
|
+
details: {
|
|
933
|
+
source: "backend-bootstrap",
|
|
934
|
+
phase: "publishable-key-bootstrap",
|
|
935
|
+
field,
|
|
936
|
+
reason: message
|
|
937
|
+
}
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
function internalTransportError(reason) {
|
|
941
|
+
return new CapxulError({
|
|
942
|
+
code: "INTERNAL_ERROR",
|
|
943
|
+
message: `Internal error: ${reason}`,
|
|
944
|
+
details: { source: "sdk-transport", reason }
|
|
945
|
+
});
|
|
946
|
+
}
|
|
947
|
+
async function bootstrapResponseError(response, bootstrapUrl) {
|
|
948
|
+
const envelope = await readBootstrapErrorEnvelope(response);
|
|
949
|
+
const wireCode = readNonEmptyString(envelope?.error?.code);
|
|
950
|
+
const normalized = normalizeBootstrapErrorCode(wireCode);
|
|
951
|
+
const message = readNonEmptyString(envelope?.error?.message) ?? `${bootstrapUrl} failed with HTTP ${response.status}.`;
|
|
952
|
+
const backendDetails = readRecord(envelope?.error?.details);
|
|
953
|
+
return new CapxulError({
|
|
954
|
+
code: normalized.code,
|
|
955
|
+
message,
|
|
956
|
+
details: {
|
|
957
|
+
...backendDetails,
|
|
958
|
+
source: "backend-bootstrap",
|
|
959
|
+
phase: "publishable-key-bootstrap",
|
|
960
|
+
httpStatus: response.status,
|
|
961
|
+
...normalized.wireCode ? { wireCode: normalized.wireCode } : {}
|
|
962
|
+
},
|
|
963
|
+
operationId: readNonEmptyString(envelope?.error?.operationId),
|
|
964
|
+
correlationId: readNonEmptyString(envelope?.error?.correlationId),
|
|
965
|
+
retryable: typeof envelope?.error?.retryable === "boolean" ? envelope.error.retryable : void 0
|
|
966
|
+
});
|
|
967
|
+
}
|
|
968
|
+
async function readBootstrapErrorEnvelope(response) {
|
|
969
|
+
try {
|
|
970
|
+
const parsed = await response.json();
|
|
971
|
+
return typeof parsed === "object" && parsed !== null ? parsed : null;
|
|
972
|
+
} catch {
|
|
973
|
+
return null;
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
async function readBootstrapSuccessBody(response) {
|
|
977
|
+
try {
|
|
978
|
+
const parsed = await response.json();
|
|
979
|
+
return typeof parsed === "object" && parsed !== null ? parsed : {};
|
|
980
|
+
} catch {
|
|
981
|
+
throw bootstrapContractError(
|
|
982
|
+
"body",
|
|
983
|
+
"/v1/client/bootstrap returned invalid JSON."
|
|
984
|
+
);
|
|
985
|
+
}
|
|
986
|
+
}
|
|
987
|
+
function normalizeBootstrapThrownError(error) {
|
|
988
|
+
if (error instanceof CapxulError) return error;
|
|
989
|
+
return new CapxulError({
|
|
990
|
+
code: "NETWORK_ERROR",
|
|
991
|
+
message: "Publishable-key bootstrap network failure.",
|
|
992
|
+
cause: error,
|
|
993
|
+
details: {
|
|
994
|
+
source: "bootstrap-network",
|
|
995
|
+
phase: "publishable-key-bootstrap"
|
|
996
|
+
}
|
|
997
|
+
});
|
|
998
|
+
}
|
|
999
|
+
function normalizeBootstrapErrorCode(wireCode) {
|
|
1000
|
+
if (wireCode === "INTERNAL_SERVER_ERROR") {
|
|
1001
|
+
return { code: "INTERNAL_ERROR", wireCode };
|
|
1002
|
+
}
|
|
1003
|
+
if (wireCode && isCapxulErrorCode(wireCode)) {
|
|
1004
|
+
return { code: wireCode };
|
|
1005
|
+
}
|
|
1006
|
+
return wireCode ? { code: "UNKNOWN", wireCode } : { code: "UNKNOWN" };
|
|
1007
|
+
}
|
|
1008
|
+
var CAPXUL_ERROR_CODES = /* @__PURE__ */ new Set([
|
|
1009
|
+
"NOT_AUTHENTICATED",
|
|
1010
|
+
"EMAIL_DELIVERY_FAILED",
|
|
1011
|
+
"PROFILE_NOT_FOUND",
|
|
1012
|
+
"SMART_ACCOUNT_MISSING",
|
|
1013
|
+
"PLAYER_NOT_FOUND",
|
|
1014
|
+
"ACCOUNT_NOT_FOUND",
|
|
1015
|
+
"PROVIDER_ERROR",
|
|
1016
|
+
"INVALID_INPUT",
|
|
1017
|
+
"ENV_MISSING",
|
|
1018
|
+
"NOT_IMPLEMENTED",
|
|
1019
|
+
"VERIFICATION_REQUIRED",
|
|
1020
|
+
"INSUFFICIENT_BALANCE",
|
|
1021
|
+
"INVALID_RECIPIENT",
|
|
1022
|
+
"TRANSACTION_FAILED",
|
|
1023
|
+
"RATE_LIMITED",
|
|
1024
|
+
"NETWORK_ERROR",
|
|
1025
|
+
"UNKNOWN",
|
|
1026
|
+
"PERMISSION_DENIED",
|
|
1027
|
+
"API_KEY_INVALID",
|
|
1028
|
+
"API_KEY_EXPIRED",
|
|
1029
|
+
"IDEMPOTENCY_CONFLICT",
|
|
1030
|
+
"NOT_FOUND",
|
|
1031
|
+
"OPERATION_CANCELED",
|
|
1032
|
+
"OPERATION_TIMEOUT",
|
|
1033
|
+
"ACTION_REQUIRED",
|
|
1034
|
+
"KYC_REQUIRED",
|
|
1035
|
+
"POLICY_DENIED",
|
|
1036
|
+
"SAFE_NOT_READY",
|
|
1037
|
+
"PROVIDER_UNAVAILABLE",
|
|
1038
|
+
"PROVIDER_REJECTED",
|
|
1039
|
+
"RECONCILIATION_FAILED",
|
|
1040
|
+
"INTERNAL_ERROR",
|
|
1041
|
+
"QUOTE_EXPIRED",
|
|
1042
|
+
"QUOTE_NOT_FOUND"
|
|
1043
|
+
]);
|
|
1044
|
+
function isCapxulErrorCode(value) {
|
|
1045
|
+
return CAPXUL_ERROR_CODES.has(value);
|
|
1046
|
+
}
|
|
1047
|
+
function readRecord(value) {
|
|
1048
|
+
return typeof value === "object" && value !== null ? value : null;
|
|
1049
|
+
}
|
|
1050
|
+
function readNonEmptyString(value) {
|
|
1051
|
+
return typeof value === "string" && value.trim().length > 0 ? value.trim() : null;
|
|
1052
|
+
}
|
|
901
1053
|
|
|
902
1054
|
// src/core/auth.ts
|
|
903
1055
|
function createAuthClient(config = {}) {
|
|
@@ -952,13 +1104,16 @@ function createAuthClient(config = {}) {
|
|
|
952
1104
|
email: signIn.user.email,
|
|
953
1105
|
token: signIn.token,
|
|
954
1106
|
convexJwt,
|
|
955
|
-
expiresAt: new Date(
|
|
1107
|
+
expiresAt: new Date(
|
|
1108
|
+
Date.now() + 30 * 24 * 60 * 60 * 1e3
|
|
1109
|
+
).toISOString()
|
|
956
1110
|
};
|
|
957
1111
|
sessionStore.set(session);
|
|
958
1112
|
if (config.auth?.createDataClient) {
|
|
959
1113
|
try {
|
|
960
1114
|
dataClient = await config.auth.createDataClient(session);
|
|
961
1115
|
mutableConfig(config).data = dataClient;
|
|
1116
|
+
transport.markAuthenticated({ dataClient });
|
|
962
1117
|
} catch (cause) {
|
|
963
1118
|
return [
|
|
964
1119
|
new CapxulError({
|
|
@@ -970,13 +1125,76 @@ function createAuthClient(config = {}) {
|
|
|
970
1125
|
];
|
|
971
1126
|
}
|
|
972
1127
|
}
|
|
973
|
-
|
|
1128
|
+
if (!dataClient) {
|
|
1129
|
+
return [
|
|
1130
|
+
new CapxulError({
|
|
1131
|
+
code: "NOT_AUTHENTICATED",
|
|
1132
|
+
message: "Auth bootstrap requires an authenticated Convex data client."
|
|
1133
|
+
}),
|
|
1134
|
+
null
|
|
1135
|
+
];
|
|
1136
|
+
}
|
|
1137
|
+
try {
|
|
1138
|
+
const resolution = await dataClient.mutation(
|
|
1139
|
+
api.authBootstrap.resolveAfterOtp,
|
|
1140
|
+
{
|
|
1141
|
+
email: session.email,
|
|
1142
|
+
sessionToken: session.token
|
|
1143
|
+
}
|
|
1144
|
+
);
|
|
1145
|
+
if (resolution.kind === "existing_member") {
|
|
1146
|
+
return [null, { ...resolution, session }];
|
|
1147
|
+
}
|
|
1148
|
+
return [null, { ...resolution, session }];
|
|
1149
|
+
} catch (cause) {
|
|
1150
|
+
return [fromConvexError(cause), null];
|
|
1151
|
+
}
|
|
1152
|
+
},
|
|
1153
|
+
completeBootstrap: async (input) => {
|
|
1154
|
+
const session = sessionStore.get();
|
|
1155
|
+
const data = dataClient ?? config.data;
|
|
1156
|
+
if (!session || !data) {
|
|
1157
|
+
return [
|
|
1158
|
+
new CapxulError({
|
|
1159
|
+
code: "INVALID_INPUT",
|
|
1160
|
+
message: "completeBootstrap requires the OTP-verified session that issued the bootstrap token."
|
|
1161
|
+
}),
|
|
1162
|
+
null
|
|
1163
|
+
];
|
|
1164
|
+
}
|
|
1165
|
+
if (input.signerProvider.kind !== "local-private-key") {
|
|
1166
|
+
return [
|
|
1167
|
+
new CapxulError({
|
|
1168
|
+
code: "INVALID_INPUT",
|
|
1169
|
+
message: "completeBootstrap currently supports local-private-key signer providers only."
|
|
1170
|
+
}),
|
|
1171
|
+
null
|
|
1172
|
+
];
|
|
1173
|
+
}
|
|
1174
|
+
try {
|
|
1175
|
+
const result = await data.mutation(api.authBootstrap.completeBootstrap, {
|
|
1176
|
+
bootstrapToken: input.bootstrapToken,
|
|
1177
|
+
sessionToken: session.token,
|
|
1178
|
+
username: input.username,
|
|
1179
|
+
displayName: input.displayName,
|
|
1180
|
+
countryCode: input.countryCode,
|
|
1181
|
+
signerProvider: input.signerProvider
|
|
1182
|
+
});
|
|
1183
|
+
return [null, { kind: "authenticated", session, ...result }];
|
|
1184
|
+
} catch (cause) {
|
|
1185
|
+
return [
|
|
1186
|
+
fromConvexError(cause),
|
|
1187
|
+
null
|
|
1188
|
+
];
|
|
1189
|
+
}
|
|
974
1190
|
},
|
|
975
1191
|
getSession: async () => [null, sessionStore.get()],
|
|
976
1192
|
signOut: async () => {
|
|
977
1193
|
sessionStore.clear();
|
|
978
1194
|
dataClient = null;
|
|
979
1195
|
mutableConfig(config).data = void 0;
|
|
1196
|
+
const transport = getTransport();
|
|
1197
|
+
transport?.clearAuth();
|
|
980
1198
|
return [null, void 0];
|
|
981
1199
|
},
|
|
982
1200
|
serviceTokenMint: async () => stub("auth.serviceTokenMint"),
|
|
@@ -1030,16 +1248,19 @@ async function postBetterAuth(transport, path, body, code, signal) {
|
|
|
1030
1248
|
body: JSON.stringify(body),
|
|
1031
1249
|
signal
|
|
1032
1250
|
});
|
|
1251
|
+
const text = await response.text();
|
|
1033
1252
|
if (!response.ok) {
|
|
1253
|
+
const parsedError = parseBetterAuthError(text);
|
|
1034
1254
|
return [
|
|
1035
1255
|
new CapxulError({
|
|
1036
|
-
code,
|
|
1037
|
-
message: `BetterAuth ${path} failed with HTTP ${response.status}
|
|
1256
|
+
code: parsedError.code ?? code,
|
|
1257
|
+
message: parsedError.message ?? `BetterAuth ${path} failed with HTTP ${response.status}.`,
|
|
1258
|
+
details: parsedError.details,
|
|
1259
|
+
retryable: parsedError.retryable
|
|
1038
1260
|
}),
|
|
1039
1261
|
null
|
|
1040
1262
|
];
|
|
1041
1263
|
}
|
|
1042
|
-
const text = await response.text();
|
|
1043
1264
|
return [null, text ? JSON.parse(text) : void 0];
|
|
1044
1265
|
} catch (cause) {
|
|
1045
1266
|
return [
|
|
@@ -1052,6 +1273,36 @@ async function postBetterAuth(transport, path, body, code, signal) {
|
|
|
1052
1273
|
];
|
|
1053
1274
|
}
|
|
1054
1275
|
}
|
|
1276
|
+
function parseBetterAuthError(text) {
|
|
1277
|
+
if (!text.trim()) {
|
|
1278
|
+
return {};
|
|
1279
|
+
}
|
|
1280
|
+
try {
|
|
1281
|
+
const body = JSON.parse(text);
|
|
1282
|
+
if (!body || typeof body !== "object") {
|
|
1283
|
+
return {};
|
|
1284
|
+
}
|
|
1285
|
+
const record = body;
|
|
1286
|
+
const nested = record.error && typeof record.error === "object" ? record.error : record;
|
|
1287
|
+
const code = typeof nested.code === "string" ? nested.code : void 0;
|
|
1288
|
+
const message = typeof nested.message === "string" ? nested.message : void 0;
|
|
1289
|
+
const details = nested.details && typeof nested.details === "object" ? nested.details : void 0;
|
|
1290
|
+
const correlationId = typeof nested.correlationId === "string" ? nested.correlationId : void 0;
|
|
1291
|
+
const retryable = typeof nested.retryable === "boolean" ? nested.retryable : void 0;
|
|
1292
|
+
return {
|
|
1293
|
+
code: isCapxulErrorCode2(code) ? code : void 0,
|
|
1294
|
+
message,
|
|
1295
|
+
details,
|
|
1296
|
+
correlationId,
|
|
1297
|
+
retryable
|
|
1298
|
+
};
|
|
1299
|
+
} catch {
|
|
1300
|
+
return {};
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
function isCapxulErrorCode2(code) {
|
|
1304
|
+
return code === "NOT_AUTHENTICATED" || code === "EMAIL_DELIVERY_FAILED" || code === "INVALID_INPUT" || code === "RATE_LIMITED" || code === "NETWORK_ERROR" || code === "API_KEY_INVALID" || code === "API_KEY_EXPIRED";
|
|
1305
|
+
}
|
|
1055
1306
|
async function exchangeConvexToken(transport, config, token, signal) {
|
|
1056
1307
|
const path = config.auth?.convexTokenUrl ?? "/convex/token";
|
|
1057
1308
|
try {
|
|
@@ -2294,7 +2545,7 @@ function createAuthFlowMachine(client) {
|
|
|
2294
2545
|
}),
|
|
2295
2546
|
verifyOtp: fromPromise(
|
|
2296
2547
|
async ({ input, signal }) => {
|
|
2297
|
-
const [error,
|
|
2548
|
+
const [error, result] = await client.auth.verifyOtp(
|
|
2298
2549
|
{
|
|
2299
2550
|
email: input.email,
|
|
2300
2551
|
otp: input.code
|
|
@@ -2302,7 +2553,14 @@ function createAuthFlowMachine(client) {
|
|
|
2302
2553
|
{ signal }
|
|
2303
2554
|
);
|
|
2304
2555
|
if (error) throw error;
|
|
2305
|
-
|
|
2556
|
+
if (result.kind === "bootstrap_required") {
|
|
2557
|
+
throw new CapxulError({
|
|
2558
|
+
code: "ACTION_REQUIRED",
|
|
2559
|
+
message: "OTP verified but auth bootstrap is required. Use createAuthBootstrapFlowMachine for product sign-up.",
|
|
2560
|
+
details: { reason: result.reason }
|
|
2561
|
+
});
|
|
2562
|
+
}
|
|
2563
|
+
return result.session;
|
|
2306
2564
|
}
|
|
2307
2565
|
),
|
|
2308
2566
|
signOut: fromPromise(async () => {
|
|
@@ -2550,6 +2808,345 @@ function emailDomain(email) {
|
|
|
2550
2808
|
const domain = email.split("@")[1]?.trim().toLowerCase();
|
|
2551
2809
|
return domain || "unknown";
|
|
2552
2810
|
}
|
|
2811
|
+
var initialContext = {
|
|
2812
|
+
email: null,
|
|
2813
|
+
code: null,
|
|
2814
|
+
username: null,
|
|
2815
|
+
signerProvider: null,
|
|
2816
|
+
bootstrapToken: null,
|
|
2817
|
+
bootstrapReason: null,
|
|
2818
|
+
session: null,
|
|
2819
|
+
account: null,
|
|
2820
|
+
safe: null,
|
|
2821
|
+
error: null
|
|
2822
|
+
};
|
|
2823
|
+
function createAuthBootstrapFlowMachine(client) {
|
|
2824
|
+
return setup({
|
|
2825
|
+
types: {},
|
|
2826
|
+
actors: {
|
|
2827
|
+
sendOtp: fromPromise(async ({ input, signal }) => {
|
|
2828
|
+
const [error] = await client.auth.sendOtp(
|
|
2829
|
+
{ email: input.email },
|
|
2830
|
+
{ signal }
|
|
2831
|
+
);
|
|
2832
|
+
if (error) throw error;
|
|
2833
|
+
}),
|
|
2834
|
+
verifyOtp: fromPromise(
|
|
2835
|
+
async ({ input, signal }) => {
|
|
2836
|
+
const [error, result] = await client.auth.verifyOtp(
|
|
2837
|
+
{ email: input.email, otp: input.code },
|
|
2838
|
+
{ signal }
|
|
2839
|
+
);
|
|
2840
|
+
if (error) throw error;
|
|
2841
|
+
return result;
|
|
2842
|
+
}
|
|
2843
|
+
),
|
|
2844
|
+
completeBootstrap: fromPromise(async ({ input }) => {
|
|
2845
|
+
const [error, result] = await client.auth.completeBootstrap(input);
|
|
2846
|
+
if (error) throw error;
|
|
2847
|
+
return result;
|
|
2848
|
+
}),
|
|
2849
|
+
signOut: fromPromise(async () => {
|
|
2850
|
+
const [error] = await client.auth.signOut();
|
|
2851
|
+
if (error) throw error;
|
|
2852
|
+
})
|
|
2853
|
+
},
|
|
2854
|
+
actions: {
|
|
2855
|
+
trackOtpRequested: ({ context }) => {
|
|
2856
|
+
if (!context.email) return;
|
|
2857
|
+
track("auth_otp_requested", {
|
|
2858
|
+
email_domain: emailDomain2(context.email)
|
|
2859
|
+
});
|
|
2860
|
+
},
|
|
2861
|
+
trackFailed: ({ event }) => {
|
|
2862
|
+
track("auth_failed", {
|
|
2863
|
+
auth_type: "email_otp",
|
|
2864
|
+
reason: errorFromEvent2(event).code
|
|
2865
|
+
});
|
|
2866
|
+
},
|
|
2867
|
+
trackTimeoutFailed: () => {
|
|
2868
|
+
track("auth_failed", {
|
|
2869
|
+
auth_type: "email_otp",
|
|
2870
|
+
reason: "timeout"
|
|
2871
|
+
});
|
|
2872
|
+
},
|
|
2873
|
+
trackVerified: () => {
|
|
2874
|
+
track("auth_verified", { auth_type: "email_otp" });
|
|
2875
|
+
},
|
|
2876
|
+
trackBootstrapRequired: ({ context }) => {
|
|
2877
|
+
track("auth_verified", {
|
|
2878
|
+
auth_type: "email_otp",
|
|
2879
|
+
auth_mode: context.bootstrapReason ?? "bootstrap_required"
|
|
2880
|
+
});
|
|
2881
|
+
},
|
|
2882
|
+
identifyAndTrack: ({ context }) => {
|
|
2883
|
+
if (!context.session) return;
|
|
2884
|
+
identify(context.session.authUserId, {
|
|
2885
|
+
email_domain: emailDomain2(context.session.email)
|
|
2886
|
+
});
|
|
2887
|
+
track("auth_identified", {
|
|
2888
|
+
email_domain: emailDomain2(context.session.email)
|
|
2889
|
+
});
|
|
2890
|
+
},
|
|
2891
|
+
trackSignedOut: () => {
|
|
2892
|
+
track("auth_signed_out");
|
|
2893
|
+
}
|
|
2894
|
+
}
|
|
2895
|
+
}).createMachine({
|
|
2896
|
+
id: "authBootstrap",
|
|
2897
|
+
initial: "email",
|
|
2898
|
+
context: initialContext,
|
|
2899
|
+
states: {
|
|
2900
|
+
email: {
|
|
2901
|
+
on: {
|
|
2902
|
+
ENTER_EMAIL: {
|
|
2903
|
+
actions: assign({
|
|
2904
|
+
email: ({ event }) => event.email,
|
|
2905
|
+
error: () => null
|
|
2906
|
+
})
|
|
2907
|
+
},
|
|
2908
|
+
REQUEST_OTP: { target: "sending_otp" }
|
|
2909
|
+
}
|
|
2910
|
+
},
|
|
2911
|
+
sending_otp: {
|
|
2912
|
+
invoke: {
|
|
2913
|
+
src: "sendOtp",
|
|
2914
|
+
input: ({ context }) => ({ email: requireEmail2(context) }),
|
|
2915
|
+
onDone: { target: "otp_requested", actions: "trackOtpRequested" },
|
|
2916
|
+
onError: {
|
|
2917
|
+
target: "otp_requested",
|
|
2918
|
+
actions: [
|
|
2919
|
+
assign({ error: ({ event }) => errorFromEvent2(event) }),
|
|
2920
|
+
"trackFailed"
|
|
2921
|
+
]
|
|
2922
|
+
}
|
|
2923
|
+
},
|
|
2924
|
+
after: {
|
|
2925
|
+
[FLOW_INVOKE_TIMEOUT_MS]: {
|
|
2926
|
+
target: "otp_requested",
|
|
2927
|
+
actions: [
|
|
2928
|
+
assign({ error: () => timeoutError2("sending_otp") }),
|
|
2929
|
+
"trackTimeoutFailed"
|
|
2930
|
+
]
|
|
2931
|
+
}
|
|
2932
|
+
}
|
|
2933
|
+
},
|
|
2934
|
+
otp_requested: {
|
|
2935
|
+
on: {
|
|
2936
|
+
ENTER_OTP: {
|
|
2937
|
+
actions: assign({
|
|
2938
|
+
code: ({ event }) => event.code,
|
|
2939
|
+
error: () => null
|
|
2940
|
+
})
|
|
2941
|
+
},
|
|
2942
|
+
VERIFY_OTP: { target: "verifying_otp" },
|
|
2943
|
+
BACK: { target: "email" },
|
|
2944
|
+
RESET: { target: "email", actions: assign(() => initialContext) }
|
|
2945
|
+
}
|
|
2946
|
+
},
|
|
2947
|
+
verifying_otp: {
|
|
2948
|
+
invoke: {
|
|
2949
|
+
src: "verifyOtp",
|
|
2950
|
+
input: ({ context }) => ({
|
|
2951
|
+
email: requireEmail2(context),
|
|
2952
|
+
code: requireCode(context)
|
|
2953
|
+
}),
|
|
2954
|
+
onDone: [
|
|
2955
|
+
{
|
|
2956
|
+
guard: ({ event }) => event.output.kind === "existing_member",
|
|
2957
|
+
target: "authenticated",
|
|
2958
|
+
actions: [
|
|
2959
|
+
assign({
|
|
2960
|
+
session: ({ event }) => event.output.session,
|
|
2961
|
+
account: ({ event }) => event.output.kind === "existing_member" ? event.output.account : null,
|
|
2962
|
+
username: ({ event }) => event.output.kind === "existing_member" ? event.output.username : null,
|
|
2963
|
+
safe: ({ event }) => event.output.kind === "existing_member" ? event.output.safe : null,
|
|
2964
|
+
email: () => null,
|
|
2965
|
+
error: () => null
|
|
2966
|
+
}),
|
|
2967
|
+
"trackVerified",
|
|
2968
|
+
"identifyAndTrack"
|
|
2969
|
+
]
|
|
2970
|
+
},
|
|
2971
|
+
{
|
|
2972
|
+
target: "bootstrap_required",
|
|
2973
|
+
actions: [
|
|
2974
|
+
assign({
|
|
2975
|
+
session: ({ event }) => event.output.session,
|
|
2976
|
+
bootstrapToken: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.bootstrapToken : null,
|
|
2977
|
+
bootstrapReason: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.reason : null,
|
|
2978
|
+
username: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.username ?? null : null,
|
|
2979
|
+
email: ({ event }) => event.output.kind === "bootstrap_required" ? event.output.email : null,
|
|
2980
|
+
error: () => null
|
|
2981
|
+
}),
|
|
2982
|
+
"trackVerified",
|
|
2983
|
+
"trackBootstrapRequired"
|
|
2984
|
+
]
|
|
2985
|
+
}
|
|
2986
|
+
],
|
|
2987
|
+
onError: {
|
|
2988
|
+
target: "otp_requested",
|
|
2989
|
+
actions: [
|
|
2990
|
+
assign({ error: ({ event }) => errorFromEvent2(event) }),
|
|
2991
|
+
"trackFailed"
|
|
2992
|
+
]
|
|
2993
|
+
}
|
|
2994
|
+
},
|
|
2995
|
+
after: {
|
|
2996
|
+
[FLOW_INVOKE_TIMEOUT_MS]: {
|
|
2997
|
+
target: "otp_requested",
|
|
2998
|
+
actions: [
|
|
2999
|
+
assign({ error: () => timeoutError2("verifying_otp") }),
|
|
3000
|
+
"trackTimeoutFailed"
|
|
3001
|
+
]
|
|
3002
|
+
}
|
|
3003
|
+
}
|
|
3004
|
+
},
|
|
3005
|
+
bootstrap_required: {
|
|
3006
|
+
on: {
|
|
3007
|
+
ENTER_USERNAME: {
|
|
3008
|
+
actions: assign({
|
|
3009
|
+
username: ({ event }) => event.username,
|
|
3010
|
+
error: () => null
|
|
3011
|
+
})
|
|
3012
|
+
},
|
|
3013
|
+
ENTER_SIGNER_PROVIDER: {
|
|
3014
|
+
actions: assign({
|
|
3015
|
+
signerProvider: ({ event }) => event.signerProvider,
|
|
3016
|
+
error: () => null
|
|
3017
|
+
})
|
|
3018
|
+
},
|
|
3019
|
+
COMPLETE_BOOTSTRAP: { target: "completing_bootstrap" },
|
|
3020
|
+
BACK: { target: "otp_requested" },
|
|
3021
|
+
RESET: { target: "email", actions: assign(() => initialContext) }
|
|
3022
|
+
}
|
|
3023
|
+
},
|
|
3024
|
+
completing_bootstrap: {
|
|
3025
|
+
invoke: {
|
|
3026
|
+
src: "completeBootstrap",
|
|
3027
|
+
input: ({ context }) => ({
|
|
3028
|
+
bootstrapToken: requireBootstrapToken(context),
|
|
3029
|
+
username: requireUsername(context),
|
|
3030
|
+
signerProvider: requireSignerProvider(context)
|
|
3031
|
+
}),
|
|
3032
|
+
onDone: {
|
|
3033
|
+
target: "authenticated",
|
|
3034
|
+
actions: [
|
|
3035
|
+
assign({
|
|
3036
|
+
session: ({ event }) => event.output.session,
|
|
3037
|
+
account: ({ event }) => event.output.account,
|
|
3038
|
+
username: ({ event }) => event.output.username,
|
|
3039
|
+
safe: ({ event }) => event.output.safe,
|
|
3040
|
+
bootstrapToken: () => null,
|
|
3041
|
+
bootstrapReason: () => null,
|
|
3042
|
+
signerProvider: () => null,
|
|
3043
|
+
email: () => null,
|
|
3044
|
+
error: () => null
|
|
3045
|
+
}),
|
|
3046
|
+
"identifyAndTrack"
|
|
3047
|
+
]
|
|
3048
|
+
},
|
|
3049
|
+
onError: {
|
|
3050
|
+
target: "bootstrap_required",
|
|
3051
|
+
actions: [
|
|
3052
|
+
assign({ error: ({ event }) => errorFromEvent2(event) }),
|
|
3053
|
+
"trackFailed"
|
|
3054
|
+
]
|
|
3055
|
+
}
|
|
3056
|
+
},
|
|
3057
|
+
after: {
|
|
3058
|
+
[FLOW_INVOKE_TIMEOUT_MS]: {
|
|
3059
|
+
target: "bootstrap_required",
|
|
3060
|
+
actions: [
|
|
3061
|
+
assign({ error: () => timeoutError2("completing_bootstrap") }),
|
|
3062
|
+
"trackTimeoutFailed"
|
|
3063
|
+
]
|
|
3064
|
+
}
|
|
3065
|
+
}
|
|
3066
|
+
},
|
|
3067
|
+
authenticated: {
|
|
3068
|
+
on: {
|
|
3069
|
+
SIGN_OUT: { target: "signing_out" }
|
|
3070
|
+
}
|
|
3071
|
+
},
|
|
3072
|
+
signing_out: {
|
|
3073
|
+
invoke: {
|
|
3074
|
+
src: "signOut",
|
|
3075
|
+
onDone: {
|
|
3076
|
+
target: "email",
|
|
3077
|
+
actions: [
|
|
3078
|
+
assign(() => initialContext),
|
|
3079
|
+
"trackSignedOut"
|
|
3080
|
+
]
|
|
3081
|
+
},
|
|
3082
|
+
onError: {
|
|
3083
|
+
target: "error",
|
|
3084
|
+
actions: assign({ error: ({ event }) => errorFromEvent2(event) })
|
|
3085
|
+
}
|
|
3086
|
+
}
|
|
3087
|
+
},
|
|
3088
|
+
error: {
|
|
3089
|
+
on: {
|
|
3090
|
+
RESET: { target: "email", actions: assign(() => initialContext) }
|
|
3091
|
+
}
|
|
3092
|
+
}
|
|
3093
|
+
}
|
|
3094
|
+
});
|
|
3095
|
+
}
|
|
3096
|
+
function requireEmail2(context) {
|
|
3097
|
+
if (!context.email) {
|
|
3098
|
+
throw Errors.invalidInput("email", "Auth bootstrap requires an email.");
|
|
3099
|
+
}
|
|
3100
|
+
return context.email;
|
|
3101
|
+
}
|
|
3102
|
+
function requireCode(context) {
|
|
3103
|
+
if (!context.code) {
|
|
3104
|
+
throw Errors.invalidInput("code", "Auth bootstrap requires an OTP code.");
|
|
3105
|
+
}
|
|
3106
|
+
return context.code;
|
|
3107
|
+
}
|
|
3108
|
+
function requireBootstrapToken(context) {
|
|
3109
|
+
if (!context.bootstrapToken) {
|
|
3110
|
+
throw Errors.invalidInput(
|
|
3111
|
+
"bootstrapToken",
|
|
3112
|
+
"Auth bootstrap requires a continuation token."
|
|
3113
|
+
);
|
|
3114
|
+
}
|
|
3115
|
+
return context.bootstrapToken;
|
|
3116
|
+
}
|
|
3117
|
+
function requireUsername(context) {
|
|
3118
|
+
if (!context.username) {
|
|
3119
|
+
throw Errors.invalidInput("username", "Auth bootstrap requires a username.");
|
|
3120
|
+
}
|
|
3121
|
+
return context.username;
|
|
3122
|
+
}
|
|
3123
|
+
function requireSignerProvider(context) {
|
|
3124
|
+
if (!context.signerProvider) {
|
|
3125
|
+
throw Errors.invalidInput(
|
|
3126
|
+
"signerProvider",
|
|
3127
|
+
"Auth bootstrap requires a signer provider."
|
|
3128
|
+
);
|
|
3129
|
+
}
|
|
3130
|
+
return context.signerProvider;
|
|
3131
|
+
}
|
|
3132
|
+
function errorFromEvent2(event) {
|
|
3133
|
+
const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
|
|
3134
|
+
if (cause instanceof CapxulError || cause instanceof CapxulError2) {
|
|
3135
|
+
return cause;
|
|
3136
|
+
}
|
|
3137
|
+
return Errors.providerError("auth", "bootstrap", cause);
|
|
3138
|
+
}
|
|
3139
|
+
function timeoutError2(state) {
|
|
3140
|
+
return Errors.providerError(
|
|
3141
|
+
"auth",
|
|
3142
|
+
"bootstrap",
|
|
3143
|
+
new Error(`timeout: ${state} exceeded ${FLOW_INVOKE_TIMEOUT_MS}ms`)
|
|
3144
|
+
);
|
|
3145
|
+
}
|
|
3146
|
+
function emailDomain2(email) {
|
|
3147
|
+
const domain = email.split("@")[1]?.trim().toLowerCase();
|
|
3148
|
+
return domain || "unknown";
|
|
3149
|
+
}
|
|
2553
3150
|
function createProvisioningMachine(client) {
|
|
2554
3151
|
return setup({
|
|
2555
3152
|
types: {},
|
|
@@ -2622,13 +3219,13 @@ function createProvisioningMachine(client) {
|
|
|
2622
3219
|
},
|
|
2623
3220
|
onError: {
|
|
2624
3221
|
target: "error",
|
|
2625
|
-
actions: assign({ error: ({ event }) =>
|
|
3222
|
+
actions: assign({ error: ({ event }) => errorFromEvent3(event) })
|
|
2626
3223
|
}
|
|
2627
3224
|
},
|
|
2628
3225
|
after: {
|
|
2629
3226
|
[FLOW_INVOKE_TIMEOUT_MS]: {
|
|
2630
3227
|
target: "error",
|
|
2631
|
-
actions: assign({ error: () =>
|
|
3228
|
+
actions: assign({ error: () => timeoutError3() })
|
|
2632
3229
|
}
|
|
2633
3230
|
}
|
|
2634
3231
|
},
|
|
@@ -2646,7 +3243,7 @@ function createProvisioningMachine(client) {
|
|
|
2646
3243
|
* this payload on its `onDone` transition and branches via guards
|
|
2647
3244
|
* on `event.output.error`.
|
|
2648
3245
|
*/
|
|
2649
|
-
output: ({ context }) => context.error ? { error: context.error } : context.account ? { account: context.account } : { error:
|
|
3246
|
+
output: ({ context }) => context.error ? { error: context.error } : context.account ? { account: context.account } : { error: timeoutError3() }
|
|
2650
3247
|
});
|
|
2651
3248
|
}
|
|
2652
3249
|
function requireProvisionInput(context) {
|
|
@@ -2658,13 +3255,13 @@ function requireProvisionInput(context) {
|
|
|
2658
3255
|
}
|
|
2659
3256
|
return context.input;
|
|
2660
3257
|
}
|
|
2661
|
-
function
|
|
3258
|
+
function errorFromEvent3(event) {
|
|
2662
3259
|
const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
|
|
2663
3260
|
if (cause instanceof CapxulError) return cause;
|
|
2664
3261
|
if (cause instanceof CapxulError2) return cause;
|
|
2665
3262
|
return Errors.providerError("provisioning", "flow", cause);
|
|
2666
3263
|
}
|
|
2667
|
-
function
|
|
3264
|
+
function timeoutError3() {
|
|
2668
3265
|
return Errors.providerError(
|
|
2669
3266
|
"provisioning",
|
|
2670
3267
|
"flow",
|
|
@@ -2757,7 +3354,7 @@ function createOnboardingFlowMachine(client) {
|
|
|
2757
3354
|
error: ({ event }) => extractChildErrorOrFallback(event)
|
|
2758
3355
|
}),
|
|
2759
3356
|
assignChildThrown: assign({
|
|
2760
|
-
error: ({ event }) =>
|
|
3357
|
+
error: ({ event }) => errorFromEvent4(event)
|
|
2761
3358
|
}),
|
|
2762
3359
|
assignAccountFromChild: assign({
|
|
2763
3360
|
account: ({ event }) => extractChildAccountOrNull(event)
|
|
@@ -2919,7 +3516,7 @@ function extractChildAccountOrNull(event) {
|
|
|
2919
3516
|
if (output && "account" in output && output.account) return output.account;
|
|
2920
3517
|
return null;
|
|
2921
3518
|
}
|
|
2922
|
-
function
|
|
3519
|
+
function errorFromEvent4(event) {
|
|
2923
3520
|
const cause = typeof event === "object" && event !== null && "error" in event ? event.error : event;
|
|
2924
3521
|
if (cause instanceof CapxulError) return cause;
|
|
2925
3522
|
if (cause instanceof CapxulError2) return cause;
|
|
@@ -2951,6 +3548,7 @@ function createCapxulClient(config = {}) {
|
|
|
2951
3548
|
const client = clientWithoutFlows;
|
|
2952
3549
|
client.flows = {
|
|
2953
3550
|
auth: () => createAuthFlowMachine(client),
|
|
3551
|
+
authBootstrap: () => createAuthBootstrapFlowMachine(client),
|
|
2954
3552
|
onboarding: () => createOnboardingFlowMachine(client),
|
|
2955
3553
|
provisioning: () => createProvisioningMachine(client)
|
|
2956
3554
|
};
|
|
@@ -3055,4 +3653,4 @@ function isWebhookEvent(value) {
|
|
|
3055
3653
|
return typeof candidate.id === "string" && typeof candidate.type === "string" && typeof candidate.createdAt === "string" && (candidate.operationId === void 0 || typeof candidate.operationId === "string") && (candidate.correlationId === void 0 || typeof candidate.correlationId === "string") && !!candidate.data && typeof candidate.data === "object" && !Array.isArray(candidate.data);
|
|
3056
3654
|
}
|
|
3057
3655
|
|
|
3058
|
-
export { CapxulError, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };
|
|
3656
|
+
export { CapxulError, createAuthBootstrapFlowMachine, createAuthFlowMachine, createCapxulClient, createLocalSigner, createOnboardingFlowMachine, createProvisioningMachine as createProvisioningFlowMachine, makeHttpTransport, matchAction, matchError, matchStatus, toAccountId, toApiKeyId, toBalanceLedgerEntryId, toDocumentId, toEmail, toExternalAccountId, toKybProfileId, toKycProfileId, toMemberId, toOperationId, toOrganizationId, toPaymentId, toPhoneNumber, toSafeId, toSubAccountId, toTokenTransferId, toTransferId, toTreasuryId, toUsername, toVirtualAccountId, toVirtualCardId, toWebhookEndpointId, toWebhookEventId, toWithdrawalId, tryCatch, verifyWebhook };
|