@capxul/sdk-react 0.2.0-alpha.5 → 1.0.0-alpha.10
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.d.mts +442 -43
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +1057 -96
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -7
package/dist/index.mjs
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { createContext, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
+
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState } from "react";
|
|
3
3
|
import { QueryClient, QueryClientProvider, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
4
|
-
import { createCapxulClient } from "@capxul/sdk";
|
|
5
|
-
import { jsx } from "react/jsx-runtime";
|
|
6
|
-
import { Errors } from "@capxul/config";
|
|
4
|
+
import { captureExceptionSync, createCapxulClient, isSettingUpLifecycle } from "@capxul/sdk";
|
|
5
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
7
6
|
//#region src/internal/capxul-bootstrap-context.tsx
|
|
8
7
|
const CapxulBootstrapContext = createContext(null);
|
|
9
8
|
function CapxulBootstrapProvider({ value, children }) {
|
|
@@ -19,7 +18,8 @@ function useCapxul() {
|
|
|
19
18
|
}
|
|
20
19
|
//#endregion
|
|
21
20
|
//#region src/internal/capxul-client-context.tsx
|
|
22
|
-
const
|
|
21
|
+
const MISSING_CAPXUL_CLIENT_PROVIDER = Symbol("MISSING_CAPXUL_CLIENT_PROVIDER");
|
|
22
|
+
const CapxulClientContext = createContext(MISSING_CAPXUL_CLIENT_PROVIDER);
|
|
23
23
|
function CapxulClientProvider({ client, children }) {
|
|
24
24
|
return /* @__PURE__ */ jsx(CapxulClientContext.Provider, {
|
|
25
25
|
value: client,
|
|
@@ -37,7 +37,9 @@ function useCapxulClient() {
|
|
|
37
37
|
* client resolves, rather than throwing during bootstrap.
|
|
38
38
|
*/
|
|
39
39
|
function useCapxulClientOrNull() {
|
|
40
|
-
|
|
40
|
+
const client = useContext(CapxulClientContext);
|
|
41
|
+
if (client === MISSING_CAPXUL_CLIENT_PROVIDER) throw new Error("useCapxulClient must be used within <CapxulProvider>");
|
|
42
|
+
return client;
|
|
41
43
|
}
|
|
42
44
|
//#endregion
|
|
43
45
|
//#region src/provider.tsx
|
|
@@ -50,10 +52,22 @@ function makeDefaultQueryClient() {
|
|
|
50
52
|
mutations: { retry: 0 }
|
|
51
53
|
} });
|
|
52
54
|
}
|
|
55
|
+
function isCapxulQueryKey(queryKey) {
|
|
56
|
+
return queryKey[0] === "capxul";
|
|
57
|
+
}
|
|
58
|
+
function clearClientScopedQueries(queryClient, ownsQueryClient) {
|
|
59
|
+
if (ownsQueryClient) {
|
|
60
|
+
queryClient.clear();
|
|
61
|
+
return;
|
|
62
|
+
}
|
|
63
|
+
queryClient.removeQueries({ predicate: (query) => isCapxulQueryKey(query.queryKey) });
|
|
64
|
+
}
|
|
53
65
|
function CapxulProvider(props) {
|
|
54
|
-
const { publishableKey, client: injectedClient, requirement,
|
|
66
|
+
const { publishableKey, client: injectedClient, requirement, signer, queryClient, children } = props;
|
|
55
67
|
const [resolvedQueryClient] = useState(() => queryClient ?? makeDefaultQueryClient());
|
|
68
|
+
const [ownsQueryClient] = useState(() => queryClient === void 0);
|
|
56
69
|
const [client, setClient] = useState(injectedClient ?? null);
|
|
70
|
+
const previousClientRef = useRef(injectedClient ?? null);
|
|
57
71
|
const [status, setStatus] = useState(injectedClient === void 0 ? "bootstrapping" : "ready");
|
|
58
72
|
const [error, setError] = useState(null);
|
|
59
73
|
const [attempt, setAttempt] = useState(0);
|
|
@@ -71,10 +85,6 @@ function CapxulProvider(props) {
|
|
|
71
85
|
const result = await createCapxulClient({
|
|
72
86
|
publishableKey,
|
|
73
87
|
...requirement === void 0 ? {} : { requirement },
|
|
74
|
-
...origin === void 0 ? {} : { origin },
|
|
75
|
-
...bootstrapBaseUrl === void 0 ? {} : { bootstrapBaseUrl },
|
|
76
|
-
...authCache === void 0 ? {} : { authCache },
|
|
77
|
-
...invokeTimeoutMs === void 0 ? {} : { invokeTimeoutMs },
|
|
78
88
|
...signer === void 0 ? {} : { signer }
|
|
79
89
|
});
|
|
80
90
|
if (cancelled) {
|
|
@@ -97,10 +107,6 @@ function CapxulProvider(props) {
|
|
|
97
107
|
}, [
|
|
98
108
|
publishableKey,
|
|
99
109
|
requirement,
|
|
100
|
-
origin,
|
|
101
|
-
bootstrapBaseUrl,
|
|
102
|
-
authCache,
|
|
103
|
-
invokeTimeoutMs,
|
|
104
110
|
signer,
|
|
105
111
|
attempt
|
|
106
112
|
]);
|
|
@@ -110,6 +116,15 @@ function CapxulProvider(props) {
|
|
|
110
116
|
setStatus("ready");
|
|
111
117
|
setError(null);
|
|
112
118
|
}, [injectedClient]);
|
|
119
|
+
useEffect(() => {
|
|
120
|
+
const previous = previousClientRef.current;
|
|
121
|
+
if (previous !== null && previous !== client) clearClientScopedQueries(resolvedQueryClient, ownsQueryClient);
|
|
122
|
+
previousClientRef.current = client;
|
|
123
|
+
}, [
|
|
124
|
+
client,
|
|
125
|
+
ownsQueryClient,
|
|
126
|
+
resolvedQueryClient
|
|
127
|
+
]);
|
|
113
128
|
const bootstrapState = useMemo(() => ({
|
|
114
129
|
status,
|
|
115
130
|
error,
|
|
@@ -132,6 +147,159 @@ function CapxulProvider(props) {
|
|
|
132
147
|
});
|
|
133
148
|
}
|
|
134
149
|
//#endregion
|
|
150
|
+
//#region ../errors/src/errors.ts
|
|
151
|
+
const CAPXUL_ERROR_CODES = [
|
|
152
|
+
"NOT_AUTHENTICATED",
|
|
153
|
+
"EMAIL_DELIVERY_FAILED",
|
|
154
|
+
"PROFILE_NOT_FOUND",
|
|
155
|
+
"SMART_ACCOUNT_MISSING",
|
|
156
|
+
"PLAYER_NOT_FOUND",
|
|
157
|
+
"ACCOUNT_NOT_FOUND",
|
|
158
|
+
"PROVIDER_ERROR",
|
|
159
|
+
"INVALID_INPUT",
|
|
160
|
+
"ENV_MISSING",
|
|
161
|
+
"NOT_IMPLEMENTED",
|
|
162
|
+
"VERIFICATION_REQUIRED",
|
|
163
|
+
"INSUFFICIENT_BALANCE",
|
|
164
|
+
"INVALID_RECIPIENT",
|
|
165
|
+
"ROLE_PERMISSION_DENIED",
|
|
166
|
+
"TRANSACTION_FAILED",
|
|
167
|
+
"RATE_LIMITED",
|
|
168
|
+
"NETWORK_ERROR",
|
|
169
|
+
"UNKNOWN",
|
|
170
|
+
"OTP_EXPIRED",
|
|
171
|
+
"SIGNER_REJECTED",
|
|
172
|
+
"CANCELLED",
|
|
173
|
+
"WRONG_STATE"
|
|
174
|
+
];
|
|
175
|
+
var CapxulError = class extends Error {
|
|
176
|
+
code;
|
|
177
|
+
details;
|
|
178
|
+
correlationId;
|
|
179
|
+
layer;
|
|
180
|
+
constructor(code, message, options = {}) {
|
|
181
|
+
super(message, "cause" in options ? { cause: options.cause } : void 0);
|
|
182
|
+
this.name = "CapxulError";
|
|
183
|
+
this.code = code;
|
|
184
|
+
if (options.details !== void 0) this.details = options.details;
|
|
185
|
+
if (options.correlationId !== void 0) this.correlationId = options.correlationId;
|
|
186
|
+
if (options.layer !== void 0) this.layer = options.layer;
|
|
187
|
+
}
|
|
188
|
+
};
|
|
189
|
+
function isCapxulError(value) {
|
|
190
|
+
return value instanceof CapxulError;
|
|
191
|
+
}
|
|
192
|
+
const Errors = {
|
|
193
|
+
notAuthenticated: (message, opts) => new CapxulError("NOT_AUTHENTICATED", message ?? "Not authenticated", opts?.failure_mode ? { details: { failure_mode: opts.failure_mode } } : void 0),
|
|
194
|
+
emailDeliveryFailed: (detail) => new CapxulError("EMAIL_DELIVERY_FAILED", "Failed to send email", { details: { detail } }),
|
|
195
|
+
profileNotFound: (authUserId) => new CapxulError("PROFILE_NOT_FOUND", `Profile not found for user ${authUserId}`, { details: { authUserId } }),
|
|
196
|
+
smartAccountMissing: (authUserId) => new CapxulError("SMART_ACCOUNT_MISSING", "Smart account not provisioned", { details: { authUserId } }),
|
|
197
|
+
playerNotFound: (playerId) => new CapxulError("PLAYER_NOT_FOUND", playerId ? `Openfort player ${playerId} not found` : "Openfort player not found", playerId === void 0 ? void 0 : { details: { playerId } }),
|
|
198
|
+
accountNotFound: (accountId) => new CapxulError("ACCOUNT_NOT_FOUND", accountId ? `Openfort account ${accountId} not found` : "Openfort account not found", accountId === void 0 ? void 0 : { details: { accountId } }),
|
|
199
|
+
providerError: (provider, operation, cause, opts) => {
|
|
200
|
+
const details = {
|
|
201
|
+
provider,
|
|
202
|
+
operation
|
|
203
|
+
};
|
|
204
|
+
if (opts?.failure_mode) details.failure_mode = opts.failure_mode;
|
|
205
|
+
return new CapxulError("PROVIDER_ERROR", `Provider error: ${provider} ${operation}`, {
|
|
206
|
+
cause,
|
|
207
|
+
details
|
|
208
|
+
});
|
|
209
|
+
},
|
|
210
|
+
invalidInput: (field, reason) => new CapxulError("INVALID_INPUT", `Invalid ${field}: ${reason}`, { details: {
|
|
211
|
+
field,
|
|
212
|
+
reason
|
|
213
|
+
} }),
|
|
214
|
+
envMissing: (name) => new CapxulError("ENV_MISSING", `Environment variable ${name} not configured`, { details: { name } }),
|
|
215
|
+
notImplemented: (domain, method) => new CapxulError("NOT_IMPLEMENTED", `${domain}.${method} is not yet implemented. This feature is planned for a future release.`, { details: {
|
|
216
|
+
domain,
|
|
217
|
+
method
|
|
218
|
+
} }),
|
|
219
|
+
/**
|
|
220
|
+
* Sibling factory to {@link Errors.providerError} for the per-state timeout
|
|
221
|
+
* path in flows (initially ProvisioningFlow's mint_openfort / deploy_safe /
|
|
222
|
+
* register_indexer `after:` timers). Same `PROVIDER_ERROR` code as
|
|
223
|
+
* `providerError`, plus a `details.reason: "timeout"` discriminator so
|
|
224
|
+
* downstream observers can distinguish failure modes without parsing the
|
|
225
|
+
* message string. The redacted message names the timeout budget; the
|
|
226
|
+
* native `cause` carries the same information for `reportError` fidelity.
|
|
227
|
+
*/
|
|
228
|
+
providerTimeout: (provider, operation, timeoutMs) => new CapxulError("PROVIDER_ERROR", `Provider error: ${provider} ${operation} (timeout exceeded ${timeoutMs}ms)`, {
|
|
229
|
+
details: {
|
|
230
|
+
provider,
|
|
231
|
+
operation,
|
|
232
|
+
reason: "timeout"
|
|
233
|
+
},
|
|
234
|
+
cause: /* @__PURE__ */ new Error(`timeout: ${operation} exceeded ${timeoutMs}ms`)
|
|
235
|
+
}),
|
|
236
|
+
verificationRequired: (details) => {
|
|
237
|
+
return new CapxulError("VERIFICATION_REQUIRED", "rail" in details ? `Verification is required before ${details.rail} can use ${details.currentKind}.` : `Verification tier ${details.requiredTier} is required.`, { details });
|
|
238
|
+
},
|
|
239
|
+
insufficientBalance: (asset, available, required) => new CapxulError("INSUFFICIENT_BALANCE", `Insufficient ${asset} balance`, { details: {
|
|
240
|
+
asset,
|
|
241
|
+
available,
|
|
242
|
+
required
|
|
243
|
+
} }),
|
|
244
|
+
invalidRecipient: (reason) => new CapxulError("INVALID_RECIPIENT", `Invalid recipient: ${reason}`, { details: { reason } }),
|
|
245
|
+
/**
|
|
246
|
+
* The org Zodiac Roles modifier REFUSED the spend on-chain (G4 · #547): the
|
|
247
|
+
* member's role condition (per-tx cap, per-day allowance, allowed recipient,
|
|
248
|
+
* or membership) was violated, so `execTransactionWithRole` reverted. This is
|
|
249
|
+
* a PERMISSION denial — explicitly NOT an `INSUFFICIENT_BALANCE` (the treasury
|
|
250
|
+
* held the funds; the role's authority is what bound). `reason` discriminates
|
|
251
|
+
* the violated condition (`over_cap` / `daily_cap` / `not_member` /
|
|
252
|
+
* `disallowed_recipient` / `condition_violation`); leak-safe — no on-chain
|
|
253
|
+
* identifiers ever enter the details.
|
|
254
|
+
*/
|
|
255
|
+
rolePermissionDenied: (details) => new CapxulError("ROLE_PERMISSION_DENIED", `Org role denied this spend on-chain (${details.reason}).`, { details: details.operation === void 0 ? { reason: details.reason } : {
|
|
256
|
+
reason: details.reason,
|
|
257
|
+
operation: details.operation
|
|
258
|
+
} }),
|
|
259
|
+
/**
|
|
260
|
+
* A transaction (or sponsored UserOp) failed. `details.reason` discriminates
|
|
261
|
+
* the failure mode for callers that must distinguish a CONFIRMED on-chain
|
|
262
|
+
* revert (`"onchain_revert"` — the op executed and reverted, e.g. a Zodiac
|
|
263
|
+
* Roles condition violation) from an inconclusive infra failure. A confirmed
|
|
264
|
+
* revert is the ONLY mode the org spend port may map to a roles denial.
|
|
265
|
+
*/
|
|
266
|
+
transactionFailed: (operation, cause, extra) => new CapxulError("TRANSACTION_FAILED", `Transaction failed: ${operation}`, {
|
|
267
|
+
cause,
|
|
268
|
+
details: extra?.reason === void 0 ? { operation } : {
|
|
269
|
+
operation,
|
|
270
|
+
reason: extra.reason
|
|
271
|
+
}
|
|
272
|
+
}),
|
|
273
|
+
rateLimited: (details) => new CapxulError("RATE_LIMITED", "Rate limit exceeded", details === void 0 ? void 0 : { details: { ...details } }),
|
|
274
|
+
networkError: (operation, cause) => new CapxulError("NETWORK_ERROR", `Network error during ${operation}`, {
|
|
275
|
+
cause,
|
|
276
|
+
details: { operation }
|
|
277
|
+
}),
|
|
278
|
+
unknown: (cause) => new CapxulError("UNKNOWN", "Unknown error", { cause }),
|
|
279
|
+
otpExpired: (details) => new CapxulError("OTP_EXPIRED", "Verification code has expired. Request a new one.", details === void 0 ? void 0 : { details: { ...details } }),
|
|
280
|
+
signerRejected: (details) => new CapxulError("SIGNER_REJECTED", "Signer rejected the request.", {
|
|
281
|
+
cause: details.cause,
|
|
282
|
+
details: details.reason === void 0 ? { source: details.source } : {
|
|
283
|
+
source: details.source,
|
|
284
|
+
reason: details.reason
|
|
285
|
+
}
|
|
286
|
+
}),
|
|
287
|
+
cancelled: (details) => new CapxulError("CANCELLED", "Operation was cancelled.", details === void 0 ? void 0 : { details: { ...details } }),
|
|
288
|
+
/**
|
|
289
|
+
* Method called from a flow state where its precondition fails (TA16). The
|
|
290
|
+
* SDK's method API short-circuits with this error before driving the
|
|
291
|
+
* internal state machine. `currentState` is the Effect-machine snapshot
|
|
292
|
+
* tag (stringified — substrate is `@effect/experimental/Machine` per
|
|
293
|
+
* `docs/canon/decisions/state-machine-substrate.md`); `validStates`
|
|
294
|
+
* enumerates the states the method accepts.
|
|
295
|
+
*/
|
|
296
|
+
wrongState: (details) => new CapxulError("WRONG_STATE", `${details.method} called from state '${details.currentState}'; valid states: ${details.validStates.join(", ")}`, { details: {
|
|
297
|
+
...details,
|
|
298
|
+
validStates: [...details.validStates]
|
|
299
|
+
} })
|
|
300
|
+
};
|
|
301
|
+
new Set(CAPXUL_ERROR_CODES);
|
|
302
|
+
//#endregion
|
|
135
303
|
//#region src/internal/require-bootstrapped-client.ts
|
|
136
304
|
/**
|
|
137
305
|
* Narrow the bootstrap-nullable client to a ready client inside a query /
|
|
@@ -149,10 +317,17 @@ function requireBootstrappedClient(client, method) {
|
|
|
149
317
|
}
|
|
150
318
|
//#endregion
|
|
151
319
|
//#region src/internal/reactivity-keys.ts
|
|
320
|
+
function actorKey(actor) {
|
|
321
|
+
if (actor === void 0) return ["pending"];
|
|
322
|
+
return actor.kind === "account" ? ["account"] : ["org", actor.orgId];
|
|
323
|
+
}
|
|
152
324
|
const capxulKeys = {
|
|
153
325
|
session: ["capxul", "session"],
|
|
154
326
|
profile: ["capxul", "profile"],
|
|
155
327
|
account: ["capxul", "account"],
|
|
328
|
+
accountLifecycle: ["capxul", "accountLifecycle"],
|
|
329
|
+
provisioning: ["capxul", "provisioning"],
|
|
330
|
+
binding: ["capxul", "binding"],
|
|
156
331
|
accountBalance: ["capxul", "accountBalance"],
|
|
157
332
|
subAccounts: (accountId) => [
|
|
158
333
|
"capxul",
|
|
@@ -182,13 +357,100 @@ const capxulKeys = {
|
|
|
182
357
|
"org",
|
|
183
358
|
orgId ?? "pending",
|
|
184
359
|
"treasury"
|
|
360
|
+
],
|
|
361
|
+
actorAddressBook: (actor) => [
|
|
362
|
+
"capxul",
|
|
363
|
+
"actor",
|
|
364
|
+
...actorKey(actor),
|
|
365
|
+
"addressBook"
|
|
366
|
+
],
|
|
367
|
+
actorAddressBookEntry: (actor, entryId) => [
|
|
368
|
+
"capxul",
|
|
369
|
+
"actor",
|
|
370
|
+
...actorKey(actor),
|
|
371
|
+
"addressBook",
|
|
372
|
+
entryId ?? "pending"
|
|
373
|
+
],
|
|
374
|
+
actorRequests: (actor) => [
|
|
375
|
+
"capxul",
|
|
376
|
+
"actor",
|
|
377
|
+
...actorKey(actor),
|
|
378
|
+
"requests"
|
|
379
|
+
],
|
|
380
|
+
actorRequest: (actor, requestId) => [
|
|
381
|
+
"capxul",
|
|
382
|
+
"actor",
|
|
383
|
+
...actorKey(actor),
|
|
384
|
+
"requests",
|
|
385
|
+
requestId ?? "pending"
|
|
386
|
+
],
|
|
387
|
+
actorInbox: (actor) => [
|
|
388
|
+
"capxul",
|
|
389
|
+
"actor",
|
|
390
|
+
...actorKey(actor),
|
|
391
|
+
"inbox"
|
|
392
|
+
],
|
|
393
|
+
actorInsightsSummary: (actor) => [
|
|
394
|
+
"capxul",
|
|
395
|
+
"actor",
|
|
396
|
+
...actorKey(actor),
|
|
397
|
+
"insights",
|
|
398
|
+
"summary"
|
|
399
|
+
],
|
|
400
|
+
actorInsightsHistory: (actor) => [
|
|
401
|
+
"capxul",
|
|
402
|
+
"actor",
|
|
403
|
+
...actorKey(actor),
|
|
404
|
+
"insights",
|
|
405
|
+
"history"
|
|
406
|
+
],
|
|
407
|
+
actorDestinationsScope: (actor) => [
|
|
408
|
+
"capxul",
|
|
409
|
+
"actor",
|
|
410
|
+
...actorKey(actor),
|
|
411
|
+
"destinations"
|
|
412
|
+
],
|
|
413
|
+
actorDestinations: (actor, refKey) => [
|
|
414
|
+
"capxul",
|
|
415
|
+
"actor",
|
|
416
|
+
...actorKey(actor),
|
|
417
|
+
"destinations",
|
|
418
|
+
refKey ?? "pending"
|
|
419
|
+
],
|
|
420
|
+
payments: ["capxul", "payments"],
|
|
421
|
+
payment: (paymentId) => [
|
|
422
|
+
"capxul",
|
|
423
|
+
"payments",
|
|
424
|
+
paymentId ?? "pending"
|
|
425
|
+
],
|
|
426
|
+
paymentRequests: ["capxul", "paymentRequests"],
|
|
427
|
+
payrollRoster: (orgId) => [
|
|
428
|
+
"capxul",
|
|
429
|
+
"org",
|
|
430
|
+
orgId ?? "pending",
|
|
431
|
+
"payroll",
|
|
432
|
+
"roster"
|
|
185
433
|
]
|
|
186
434
|
};
|
|
187
435
|
//#endregion
|
|
188
436
|
//#region src/internal/unwrap-capxul-result.ts
|
|
189
|
-
/**
|
|
190
|
-
|
|
437
|
+
/**
|
|
438
|
+
* Unwrap a `CapxulResult` for TanStack query/mutation functions —
|
|
439
|
+
* throws into error paths, optionally reporting the error to telemetry first.
|
|
440
|
+
*
|
|
441
|
+
* When `telemetry` is provided and the result is `{ ok: false }`,
|
|
442
|
+
* `captureExceptionSync` is called (fire-and-forget) before the throw. `operation`
|
|
443
|
+
* tags the telemetry event so query reads and mutation writes stay
|
|
444
|
+
* distinguishable in error tracking (defaults to `"query"`).
|
|
445
|
+
*/
|
|
446
|
+
function unwrapCapxulResult(result, telemetry, operation = "query") {
|
|
191
447
|
if (result.ok) return result.value;
|
|
448
|
+
if (telemetry) try {
|
|
449
|
+
captureExceptionSync(telemetry, result.error, {
|
|
450
|
+
layer: "react-query",
|
|
451
|
+
operation
|
|
452
|
+
});
|
|
453
|
+
} catch {}
|
|
192
454
|
throw result.error;
|
|
193
455
|
}
|
|
194
456
|
//#endregion
|
|
@@ -197,7 +459,7 @@ function useCapxulSession() {
|
|
|
197
459
|
const client = useCapxulClientOrNull();
|
|
198
460
|
return useQuery({
|
|
199
461
|
queryKey: capxulKeys.session,
|
|
200
|
-
queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "auth.getSession").auth.getSession()),
|
|
462
|
+
queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "auth.getSession").auth.getSession(), client._internal.telemetry),
|
|
201
463
|
enabled: client !== null
|
|
202
464
|
});
|
|
203
465
|
}
|
|
@@ -207,19 +469,84 @@ function useCapxulProfile() {
|
|
|
207
469
|
const client = useCapxulClientOrNull();
|
|
208
470
|
return useQuery({
|
|
209
471
|
queryKey: capxulKeys.profile,
|
|
210
|
-
queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "identity.loadCurrent").identity.loadCurrent()),
|
|
472
|
+
queryFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "identity.loadCurrent").identity.loadCurrent(), client._internal.telemetry),
|
|
211
473
|
enabled: client !== null
|
|
212
474
|
});
|
|
213
475
|
}
|
|
214
476
|
//#endregion
|
|
215
|
-
//#region src/
|
|
216
|
-
|
|
477
|
+
//#region src/internal/is-vitest-runtime.ts
|
|
478
|
+
/** True under Vitest — disables hook polling intervals that fight fake timers. */
|
|
479
|
+
function isVitestRuntime() {
|
|
480
|
+
return typeof process !== "undefined" && process.env["VITEST"] === "true";
|
|
481
|
+
}
|
|
482
|
+
//#endregion
|
|
483
|
+
//#region src/internal/invalidate-auth-boundary.ts
|
|
484
|
+
/** Background refetch after verifyOtp — avoids hard reset cancel errors in UI. */
|
|
485
|
+
async function invalidateAuthBoundary(queryClient) {
|
|
486
|
+
await Promise.all([
|
|
487
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.session }),
|
|
488
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.profile }),
|
|
489
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.accountLifecycle }),
|
|
490
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance })
|
|
491
|
+
]);
|
|
492
|
+
}
|
|
493
|
+
/** Hard reset after signOut — drop cached authenticated rows immediately. */
|
|
494
|
+
async function resetAuthBoundary(queryClient) {
|
|
495
|
+
await queryClient.cancelQueries({ queryKey: capxulKeys.accountBalance });
|
|
496
|
+
await Promise.all([
|
|
497
|
+
queryClient.resetQueries({ queryKey: capxulKeys.session }),
|
|
498
|
+
queryClient.resetQueries({ queryKey: capxulKeys.profile }),
|
|
499
|
+
queryClient.resetQueries({ queryKey: capxulKeys.accountLifecycle }),
|
|
500
|
+
queryClient.resetQueries({ queryKey: capxulKeys.accountBalance })
|
|
501
|
+
]);
|
|
502
|
+
}
|
|
503
|
+
//#endregion
|
|
504
|
+
//#region src/hooks/use-capxul-account-lifecycle.ts
|
|
505
|
+
const LOADING_LIFECYCLE = { status: "loading" };
|
|
506
|
+
function useCapxulAccountLifecycle() {
|
|
217
507
|
const client = useCapxulClientOrNull();
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
508
|
+
const queryClient = useQueryClient();
|
|
509
|
+
const query = useQuery({
|
|
510
|
+
queryKey: capxulKeys.accountLifecycle,
|
|
511
|
+
queryFn: async () => {
|
|
512
|
+
const bootstrappedClient = requireBootstrappedClient(client, "account.getLifecycle");
|
|
513
|
+
return unwrapCapxulResult(await bootstrappedClient.account.getLifecycle(), bootstrappedClient._internal.telemetry);
|
|
514
|
+
},
|
|
515
|
+
enabled: client !== null,
|
|
516
|
+
refetchInterval: (q) => {
|
|
517
|
+
if (isVitestRuntime()) return false;
|
|
518
|
+
const data = q.state.data;
|
|
519
|
+
if (data === void 0) return false;
|
|
520
|
+
if (data.status === "loading" || isSettingUpLifecycle(data)) return 2e3;
|
|
521
|
+
return false;
|
|
522
|
+
}
|
|
523
|
+
});
|
|
524
|
+
const retryMutation = useMutation({
|
|
525
|
+
mutationFn: async () => {
|
|
526
|
+
const bootstrappedClient = requireBootstrappedClient(client, "account.retrySetup");
|
|
527
|
+
return unwrapCapxulResult(await bootstrappedClient.account.retrySetup(), bootstrappedClient._internal.telemetry, "mutation");
|
|
528
|
+
},
|
|
529
|
+
onSuccess: async () => {
|
|
530
|
+
await invalidateAuthBoundary(queryClient);
|
|
531
|
+
}
|
|
222
532
|
});
|
|
533
|
+
const lifecycle = query.data ?? LOADING_LIFECYCLE;
|
|
534
|
+
const failedError = lifecycle.status === "failed" ? lifecycle.error : null;
|
|
535
|
+
const queryError = query.isError ? query.error : null;
|
|
536
|
+
return {
|
|
537
|
+
lifecycle: queryError !== null && lifecycle.status === "loading" ? {
|
|
538
|
+
status: "failed",
|
|
539
|
+
at: "connecting",
|
|
540
|
+
error: queryError
|
|
541
|
+
} : lifecycle,
|
|
542
|
+
isSettingUp: isSettingUpLifecycle(lifecycle),
|
|
543
|
+
error: failedError ?? queryError,
|
|
544
|
+
isLoading: query.isLoading,
|
|
545
|
+
isFetching: query.isFetching,
|
|
546
|
+
isError: query.isError,
|
|
547
|
+
retry: retryMutation.mutateAsync,
|
|
548
|
+
isRetrying: retryMutation.isPending
|
|
549
|
+
};
|
|
223
550
|
}
|
|
224
551
|
//#endregion
|
|
225
552
|
//#region src/hooks/use-capxul-account-balance.ts
|
|
@@ -227,7 +554,10 @@ function useCapxulAccountBalance(options) {
|
|
|
227
554
|
const client = useCapxulClientOrNull();
|
|
228
555
|
return useQuery({
|
|
229
556
|
queryKey: capxulKeys.accountBalance,
|
|
230
|
-
queryFn: async () =>
|
|
557
|
+
queryFn: async () => {
|
|
558
|
+
const bootstrappedClient = requireBootstrappedClient(client, "accounts.read");
|
|
559
|
+
return unwrapCapxulResult(await bootstrappedClient.accounts.read(), bootstrappedClient._internal.telemetry);
|
|
560
|
+
},
|
|
231
561
|
enabled: client !== null && (options?.enabled ?? true)
|
|
232
562
|
});
|
|
233
563
|
}
|
|
@@ -237,7 +567,10 @@ function useCapxulAccountFund() {
|
|
|
237
567
|
const client = useCapxulClientOrNull();
|
|
238
568
|
const queryClient = useQueryClient();
|
|
239
569
|
return useMutation({
|
|
240
|
-
mutationFn: async (amount) =>
|
|
570
|
+
mutationFn: async (amount) => {
|
|
571
|
+
const bootstrappedClient = requireBootstrappedClient(client, "_internal.accounts.fund");
|
|
572
|
+
return unwrapCapxulResult(await bootstrappedClient._internal.accounts.fund(amount), bootstrappedClient._internal.telemetry, "mutation");
|
|
573
|
+
},
|
|
241
574
|
onSuccess: async () => {
|
|
242
575
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
|
|
243
576
|
}
|
|
@@ -247,28 +580,10 @@ function useCapxulAccountFund() {
|
|
|
247
580
|
//#region src/hooks/use-capxul-sign-in.ts
|
|
248
581
|
function useCapxulSignIn() {
|
|
249
582
|
const client = useCapxulClientOrNull();
|
|
250
|
-
return useMutation({ mutationFn: async (input) =>
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
/** Background refetch after verifyOtp — avoids hard reset cancel errors in UI. */
|
|
255
|
-
async function invalidateAuthBoundary(queryClient) {
|
|
256
|
-
await Promise.all([
|
|
257
|
-
queryClient.invalidateQueries({ queryKey: capxulKeys.session }),
|
|
258
|
-
queryClient.invalidateQueries({ queryKey: capxulKeys.profile }),
|
|
259
|
-
queryClient.invalidateQueries({ queryKey: capxulKeys.account }),
|
|
260
|
-
queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance })
|
|
261
|
-
]);
|
|
262
|
-
}
|
|
263
|
-
/** Hard reset after signOut — drop cached authenticated rows immediately. */
|
|
264
|
-
async function resetAuthBoundary(queryClient) {
|
|
265
|
-
await queryClient.cancelQueries({ queryKey: capxulKeys.accountBalance });
|
|
266
|
-
await Promise.all([
|
|
267
|
-
queryClient.resetQueries({ queryKey: capxulKeys.session }),
|
|
268
|
-
queryClient.resetQueries({ queryKey: capxulKeys.profile }),
|
|
269
|
-
queryClient.resetQueries({ queryKey: capxulKeys.account }),
|
|
270
|
-
queryClient.resetQueries({ queryKey: capxulKeys.accountBalance })
|
|
271
|
-
]);
|
|
583
|
+
return useMutation({ mutationFn: async (input) => {
|
|
584
|
+
const bootstrappedClient = requireBootstrappedClient(client, "auth.signIn");
|
|
585
|
+
return unwrapCapxulResult(await bootstrappedClient.auth.signIn(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
586
|
+
} });
|
|
272
587
|
}
|
|
273
588
|
//#endregion
|
|
274
589
|
//#region src/hooks/use-capxul-verify-otp.ts
|
|
@@ -276,8 +591,13 @@ function useCapxulVerifyOtp() {
|
|
|
276
591
|
const client = useCapxulClientOrNull();
|
|
277
592
|
const queryClient = useQueryClient();
|
|
278
593
|
return useMutation({
|
|
279
|
-
mutationFn: async (input) =>
|
|
280
|
-
|
|
594
|
+
mutationFn: async (input) => {
|
|
595
|
+
const bootstrappedClient = requireBootstrappedClient(client, "auth.verifyOtp");
|
|
596
|
+
return unwrapCapxulResult(await bootstrappedClient.auth.verifyOtp(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
597
|
+
},
|
|
598
|
+
onSuccess: async () => {
|
|
599
|
+
await invalidateAuthBoundary(queryClient);
|
|
600
|
+
}
|
|
281
601
|
});
|
|
282
602
|
}
|
|
283
603
|
//#endregion
|
|
@@ -289,21 +609,14 @@ function useCapxulSignOut() {
|
|
|
289
609
|
onMutate: async () => {
|
|
290
610
|
await queryClient.cancelQueries({ queryKey: capxulKeys.accountBalance });
|
|
291
611
|
},
|
|
292
|
-
mutationFn: async () =>
|
|
612
|
+
mutationFn: async () => {
|
|
613
|
+
const bootstrappedClient = requireBootstrappedClient(client, "auth.signOut");
|
|
614
|
+
return unwrapCapxulResult(await bootstrappedClient.auth.signOut(), bootstrappedClient._internal.telemetry, "mutation");
|
|
615
|
+
},
|
|
293
616
|
onSuccess: () => resetAuthBoundary(queryClient)
|
|
294
617
|
});
|
|
295
618
|
}
|
|
296
619
|
//#endregion
|
|
297
|
-
//#region src/hooks/use-capxul-ensure-ready.ts
|
|
298
|
-
function useCapxulEnsureReady() {
|
|
299
|
-
const client = useCapxulClientOrNull();
|
|
300
|
-
const queryClient = useQueryClient();
|
|
301
|
-
return useMutation({
|
|
302
|
-
mutationFn: async () => unwrapCapxulResult(await requireBootstrappedClient(client, "account.ensureReady").account.ensureReady()),
|
|
303
|
-
onSuccess: () => invalidateAuthBoundary(queryClient)
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
|
-
//#endregion
|
|
307
620
|
//#region src/hooks/use-capxul-sub-accounts.ts
|
|
308
621
|
function useCapxulSubAccountsList(accountId, options) {
|
|
309
622
|
const client = useCapxulClientOrNull();
|
|
@@ -311,7 +624,8 @@ function useCapxulSubAccountsList(accountId, options) {
|
|
|
311
624
|
queryKey: capxulKeys.subAccounts(accountId),
|
|
312
625
|
queryFn: async () => {
|
|
313
626
|
if (accountId === void 0) throw Errors.invalidInput("accountId", "required for subAccounts.list");
|
|
314
|
-
|
|
627
|
+
const bootstrappedClient = requireBootstrappedClient(client, "subAccounts.list");
|
|
628
|
+
return unwrapCapxulResult(await bootstrappedClient.subAccounts.list(accountId), bootstrappedClient._internal.telemetry);
|
|
315
629
|
},
|
|
316
630
|
enabled: client !== null && (options?.enabled ?? true) && accountId !== void 0
|
|
317
631
|
});
|
|
@@ -320,7 +634,10 @@ function useCapxulSubAccountCreate() {
|
|
|
320
634
|
const client = useCapxulClientOrNull();
|
|
321
635
|
const queryClient = useQueryClient();
|
|
322
636
|
return useMutation({
|
|
323
|
-
mutationFn: async (input) =>
|
|
637
|
+
mutationFn: async (input) => {
|
|
638
|
+
const bootstrappedClient = requireBootstrappedClient(client, "subAccounts.create");
|
|
639
|
+
return unwrapCapxulResult(await bootstrappedClient.subAccounts.create(input.accountId, { name: input.name }), bootstrappedClient._internal.telemetry, "mutation");
|
|
640
|
+
},
|
|
324
641
|
onSuccess: async (_value, variables) => {
|
|
325
642
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.subAccounts(variables.accountId) });
|
|
326
643
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
|
|
@@ -331,7 +648,10 @@ function useCapxulSubAccountRename() {
|
|
|
331
648
|
const client = useCapxulClientOrNull();
|
|
332
649
|
const queryClient = useQueryClient();
|
|
333
650
|
return useMutation({
|
|
334
|
-
mutationFn: async (input) =>
|
|
651
|
+
mutationFn: async (input) => {
|
|
652
|
+
const bootstrappedClient = requireBootstrappedClient(client, "subAccounts.rename");
|
|
653
|
+
return unwrapCapxulResult(await bootstrappedClient.subAccounts.rename(input.subAccountId, input.name), bootstrappedClient._internal.telemetry, "mutation");
|
|
654
|
+
},
|
|
335
655
|
onSuccess: async (_value, variables) => {
|
|
336
656
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.subAccounts(variables.accountId) });
|
|
337
657
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
|
|
@@ -342,7 +662,10 @@ function useCapxulSubAccountDelete() {
|
|
|
342
662
|
const client = useCapxulClientOrNull();
|
|
343
663
|
const queryClient = useQueryClient();
|
|
344
664
|
return useMutation({
|
|
345
|
-
mutationFn: async (input) =>
|
|
665
|
+
mutationFn: async (input) => {
|
|
666
|
+
const bootstrappedClient = requireBootstrappedClient(client, "subAccounts.delete");
|
|
667
|
+
return unwrapCapxulResult(await bootstrappedClient.subAccounts.delete(input.subAccountId), bootstrappedClient._internal.telemetry, "mutation");
|
|
668
|
+
},
|
|
346
669
|
onSuccess: async (_value, variables) => {
|
|
347
670
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.subAccounts(variables.accountId) });
|
|
348
671
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
|
|
@@ -353,11 +676,14 @@ function useCapxulTransfer() {
|
|
|
353
676
|
const client = useCapxulClientOrNull();
|
|
354
677
|
const queryClient = useQueryClient();
|
|
355
678
|
return useMutation({
|
|
356
|
-
mutationFn: async ({ from, to, amount }) =>
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
679
|
+
mutationFn: async ({ from, to, amount }) => {
|
|
680
|
+
const bootstrappedClient = requireBootstrappedClient(client, "subAccounts.transfer");
|
|
681
|
+
return unwrapCapxulResult(await bootstrappedClient.subAccounts.transfer({
|
|
682
|
+
from,
|
|
683
|
+
to,
|
|
684
|
+
amount
|
|
685
|
+
}), bootstrappedClient._internal.telemetry, "mutation");
|
|
686
|
+
},
|
|
361
687
|
onSuccess: async (_value, variables) => {
|
|
362
688
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.subAccounts(variables.accountId) });
|
|
363
689
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance });
|
|
@@ -365,13 +691,377 @@ function useCapxulTransfer() {
|
|
|
365
691
|
});
|
|
366
692
|
}
|
|
367
693
|
//#endregion
|
|
694
|
+
//#region src/internal/invalidate-money-state.ts
|
|
695
|
+
function isPayment(value) {
|
|
696
|
+
if (typeof value !== "object" || value === null) return false;
|
|
697
|
+
const record = value;
|
|
698
|
+
return typeof record.id === "string" && typeof record.status === "string" && typeof record.paymentType === "string" && typeof record.amount === "object" && record.amount !== null;
|
|
699
|
+
}
|
|
700
|
+
function paymentsFromValue(value) {
|
|
701
|
+
if (Array.isArray(value)) return value.filter(isPayment);
|
|
702
|
+
if (isPayment(value)) return [value];
|
|
703
|
+
if (typeof value !== "object" || value === null) return [];
|
|
704
|
+
const payments = value.payments;
|
|
705
|
+
return Array.isArray(payments) ? payments.filter(isPayment) : [];
|
|
706
|
+
}
|
|
707
|
+
async function invalidateMoneyState(queryClient, input) {
|
|
708
|
+
const invalidations = [
|
|
709
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.payments }),
|
|
710
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsSummary(input.actor) }),
|
|
711
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsHistory(input.actor) })
|
|
712
|
+
];
|
|
713
|
+
if (input.payment !== void 0) invalidations.push(queryClient.invalidateQueries({ queryKey: capxulKeys.payment(input.payment.id) }));
|
|
714
|
+
if (input.actor.kind === "account") invalidations.push(queryClient.invalidateQueries({ queryKey: capxulKeys.accountBalance }));
|
|
715
|
+
else invalidations.push(queryClient.invalidateQueries({ queryKey: capxulKeys.orgTreasury(input.actor.orgId) }));
|
|
716
|
+
if (input.includeAddressBook === true) invalidations.push(queryClient.invalidateQueries({ queryKey: capxulKeys.actorAddressBook(input.actor) }));
|
|
717
|
+
await Promise.all(invalidations);
|
|
718
|
+
}
|
|
719
|
+
//#endregion
|
|
720
|
+
//#region src/hooks/use-capxul-money.ts
|
|
721
|
+
function useCapxulPay() {
|
|
722
|
+
const client = useCapxulClientOrNull();
|
|
723
|
+
const queryClient = useQueryClient();
|
|
724
|
+
return useMutation({
|
|
725
|
+
mutationFn: async (input) => {
|
|
726
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payments.pay");
|
|
727
|
+
return unwrapCapxulResult(await bootstrappedClient.payments.pay(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
728
|
+
},
|
|
729
|
+
onSuccess: async (payment) => {
|
|
730
|
+
await invalidateMoneyState(queryClient, {
|
|
731
|
+
actor: { kind: "account" },
|
|
732
|
+
payment,
|
|
733
|
+
includeAddressBook: true
|
|
734
|
+
});
|
|
735
|
+
}
|
|
736
|
+
});
|
|
737
|
+
}
|
|
738
|
+
function useCapxulPayout() {
|
|
739
|
+
const client = useCapxulClientOrNull();
|
|
740
|
+
const queryClient = useQueryClient();
|
|
741
|
+
return useMutation({
|
|
742
|
+
mutationFn: async (input) => {
|
|
743
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payments.payout");
|
|
744
|
+
return unwrapCapxulResult(await bootstrappedClient.payments.payout(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
745
|
+
},
|
|
746
|
+
onSuccess: async (payment, variables) => {
|
|
747
|
+
await invalidateMoneyState(queryClient, {
|
|
748
|
+
actor: variables.actor ?? { kind: "account" },
|
|
749
|
+
payment
|
|
750
|
+
});
|
|
751
|
+
}
|
|
752
|
+
});
|
|
753
|
+
}
|
|
754
|
+
function useCapxulWithdraw() {
|
|
755
|
+
const client = useCapxulClientOrNull();
|
|
756
|
+
const queryClient = useQueryClient();
|
|
757
|
+
return useMutation({
|
|
758
|
+
mutationFn: async (input) => {
|
|
759
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payments.withdraw");
|
|
760
|
+
return unwrapCapxulResult(await bootstrappedClient.payments.withdraw(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
761
|
+
},
|
|
762
|
+
onSuccess: async (payment) => {
|
|
763
|
+
await invalidateMoneyState(queryClient, {
|
|
764
|
+
actor: { kind: "account" },
|
|
765
|
+
payment
|
|
766
|
+
});
|
|
767
|
+
}
|
|
768
|
+
});
|
|
769
|
+
}
|
|
770
|
+
function useCapxulPayments(options) {
|
|
771
|
+
const client = useCapxulClientOrNull();
|
|
772
|
+
return useQuery({
|
|
773
|
+
queryKey: capxulKeys.payments,
|
|
774
|
+
queryFn: async () => {
|
|
775
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payments.list");
|
|
776
|
+
return unwrapCapxulResult(await bootstrappedClient.payments.list(), bootstrappedClient._internal.telemetry);
|
|
777
|
+
},
|
|
778
|
+
enabled: client !== null && (options?.enabled ?? true)
|
|
779
|
+
});
|
|
780
|
+
}
|
|
781
|
+
function useCapxulPayment(paymentId, options) {
|
|
782
|
+
const client = useCapxulClientOrNull();
|
|
783
|
+
return useQuery({
|
|
784
|
+
queryKey: capxulKeys.payment(paymentId),
|
|
785
|
+
queryFn: async () => {
|
|
786
|
+
if (paymentId === void 0) throw Errors.invalidInput("paymentId", "required for payments.get");
|
|
787
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payments.get");
|
|
788
|
+
return unwrapCapxulResult(await bootstrappedClient.payments.get(paymentId), bootstrappedClient._internal.telemetry);
|
|
789
|
+
},
|
|
790
|
+
enabled: client !== null && paymentId !== void 0 && (options?.enabled ?? true)
|
|
791
|
+
});
|
|
792
|
+
}
|
|
793
|
+
//#endregion
|
|
794
|
+
//#region src/hooks/use-capxul-actor-scope.ts
|
|
795
|
+
const capxulAccountScope = { kind: "account" };
|
|
796
|
+
function capxulOrgScope(orgId) {
|
|
797
|
+
return orgId === void 0 ? void 0 : {
|
|
798
|
+
kind: "org",
|
|
799
|
+
orgId
|
|
800
|
+
};
|
|
801
|
+
}
|
|
802
|
+
function requireActorScope(actor, operation) {
|
|
803
|
+
if (actor === void 0) throw Errors.invalidInput("actor", `required for ${operation}`);
|
|
804
|
+
return actor;
|
|
805
|
+
}
|
|
806
|
+
function actorMethods(client, actor) {
|
|
807
|
+
return actor.kind === "account" ? client.account : client.org(actor.orgId);
|
|
808
|
+
}
|
|
809
|
+
function entryIdFromData(data) {
|
|
810
|
+
if (typeof data !== "object" || data === null) return void 0;
|
|
811
|
+
const id = data.id;
|
|
812
|
+
return typeof id === "string" ? id : void 0;
|
|
813
|
+
}
|
|
814
|
+
function requestIdFromMutation(data, variables) {
|
|
815
|
+
if (typeof variables === "string") return variables;
|
|
816
|
+
if (typeof variables === "object" && variables !== null) {
|
|
817
|
+
const requestId = variables.requestId;
|
|
818
|
+
if (typeof requestId === "string") return requestId;
|
|
819
|
+
}
|
|
820
|
+
if (isPayment(data)) return void 0;
|
|
821
|
+
return entryIdFromData(data);
|
|
822
|
+
}
|
|
823
|
+
function useCapxulAddressBook(actor, options) {
|
|
824
|
+
const client = useCapxulClientOrNull();
|
|
825
|
+
return useQuery({
|
|
826
|
+
queryKey: capxulKeys.actorAddressBook(actor),
|
|
827
|
+
queryFn: async () => {
|
|
828
|
+
const bootstrappedClient = requireBootstrappedClient(client, "addressBook.list");
|
|
829
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "addressBook.list")).addressBook.list(), bootstrappedClient._internal.telemetry);
|
|
830
|
+
},
|
|
831
|
+
enabled: client !== null && actor !== void 0 && (options?.enabled ?? true)
|
|
832
|
+
});
|
|
833
|
+
}
|
|
834
|
+
function useCapxulAddressBookEntry(actor, entryId, options) {
|
|
835
|
+
const client = useCapxulClientOrNull();
|
|
836
|
+
return useQuery({
|
|
837
|
+
queryKey: capxulKeys.actorAddressBookEntry(actor, entryId),
|
|
838
|
+
queryFn: async () => {
|
|
839
|
+
if (entryId === void 0) throw Errors.invalidInput("entryId", "required for addressBook.get");
|
|
840
|
+
const bootstrappedClient = requireBootstrappedClient(client, "addressBook.get");
|
|
841
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "addressBook.get")).addressBook.get(entryId), bootstrappedClient._internal.telemetry);
|
|
842
|
+
},
|
|
843
|
+
enabled: client !== null && actor !== void 0 && entryId !== void 0 && (options?.enabled ?? true)
|
|
844
|
+
});
|
|
845
|
+
}
|
|
846
|
+
function useAddressBookMutation(actor, operation, run) {
|
|
847
|
+
const client = useCapxulClientOrNull();
|
|
848
|
+
const queryClient = useQueryClient();
|
|
849
|
+
return useMutation({
|
|
850
|
+
mutationFn: async (variables) => {
|
|
851
|
+
const bootstrappedClient = requireBootstrappedClient(client, operation);
|
|
852
|
+
return unwrapCapxulResult(await run(actorMethods(bootstrappedClient, requireActorScope(actor, operation)), variables), bootstrappedClient._internal.telemetry, "mutation");
|
|
853
|
+
},
|
|
854
|
+
onSuccess: async (data) => {
|
|
855
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorAddressBook(actor) });
|
|
856
|
+
const entryId = entryIdFromData(data);
|
|
857
|
+
if (entryId !== void 0) await queryClient.invalidateQueries({ queryKey: capxulKeys.actorAddressBookEntry(actor, entryId) });
|
|
858
|
+
}
|
|
859
|
+
});
|
|
860
|
+
}
|
|
861
|
+
const useCapxulAddAddressBookEntry = (actor = capxulAccountScope) => useAddressBookMutation(actor, "addressBook.add", (methods, input) => methods.addressBook.add(input));
|
|
862
|
+
const useCapxulHideAddressBookEntry = (actor = capxulAccountScope) => useAddressBookMutation(actor, "addressBook.hide", (methods, entryId) => methods.addressBook.hide(entryId));
|
|
863
|
+
const useCapxulUnhideAddressBookEntry = (actor = capxulAccountScope) => useAddressBookMutation(actor, "addressBook.unhide", (methods, entryId) => methods.addressBook.unhide(entryId));
|
|
864
|
+
const useCapxulLabelAddressBookEntry = (actor = capxulAccountScope) => useAddressBookMutation(actor, "addressBook.label", (methods, input) => methods.addressBook.label(input));
|
|
865
|
+
function useCapxulRequests(actor, options) {
|
|
866
|
+
const client = useCapxulClientOrNull();
|
|
867
|
+
return useQuery({
|
|
868
|
+
queryKey: capxulKeys.actorRequests(actor),
|
|
869
|
+
queryFn: async () => {
|
|
870
|
+
const bootstrappedClient = requireBootstrappedClient(client, "requests.list");
|
|
871
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "requests.list")).requests.list(), bootstrappedClient._internal.telemetry);
|
|
872
|
+
},
|
|
873
|
+
enabled: client !== null && actor !== void 0 && (options?.enabled ?? true)
|
|
874
|
+
});
|
|
875
|
+
}
|
|
876
|
+
function useCapxulRequest(actor, requestId, options) {
|
|
877
|
+
const client = useCapxulClientOrNull();
|
|
878
|
+
return useQuery({
|
|
879
|
+
queryKey: capxulKeys.actorRequest(actor, requestId),
|
|
880
|
+
queryFn: async () => {
|
|
881
|
+
if (requestId === void 0) throw Errors.invalidInput("requestId", "required for requests.get");
|
|
882
|
+
const bootstrappedClient = requireBootstrappedClient(client, "requests.get");
|
|
883
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "requests.get")).requests.get(requestId), bootstrappedClient._internal.telemetry);
|
|
884
|
+
},
|
|
885
|
+
enabled: client !== null && actor !== void 0 && requestId !== void 0 && (options?.enabled ?? true)
|
|
886
|
+
});
|
|
887
|
+
}
|
|
888
|
+
function useRequestMutation(actor, operation, run, invalidateInbox = false) {
|
|
889
|
+
const client = useCapxulClientOrNull();
|
|
890
|
+
const queryClient = useQueryClient();
|
|
891
|
+
return useMutation({
|
|
892
|
+
mutationFn: async (variables) => {
|
|
893
|
+
const bootstrappedClient = requireBootstrappedClient(client, operation);
|
|
894
|
+
return unwrapCapxulResult(await run(actorMethods(bootstrappedClient, requireActorScope(actor, operation)), variables), bootstrappedClient._internal.telemetry, "mutation");
|
|
895
|
+
},
|
|
896
|
+
onSuccess: async (data, variables) => {
|
|
897
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorRequests(actor) });
|
|
898
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorAddressBook(actor) });
|
|
899
|
+
const requestId = requestIdFromMutation(data, variables);
|
|
900
|
+
if (requestId !== void 0) await queryClient.invalidateQueries({ queryKey: capxulKeys.actorRequest(actor, requestId) });
|
|
901
|
+
if (invalidateInbox) await queryClient.invalidateQueries({ queryKey: capxulKeys.actorInbox(actor) });
|
|
902
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsSummary(actor) });
|
|
903
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsHistory(actor) });
|
|
904
|
+
if (isPayment(data)) await invalidateMoneyState(queryClient, {
|
|
905
|
+
actor: requireActorScope(actor, operation),
|
|
906
|
+
payment: data
|
|
907
|
+
});
|
|
908
|
+
}
|
|
909
|
+
});
|
|
910
|
+
}
|
|
911
|
+
const useCapxulIssueRequest = (actor = capxulAccountScope) => useRequestMutation(actor, "requests.issue", (methods, input) => methods.requests.issue(input));
|
|
912
|
+
const useCapxulCancelRequest = (actor = capxulAccountScope) => useRequestMutation(actor, "requests.cancel", (methods, requestId) => methods.requests.cancel(requestId), true);
|
|
913
|
+
const useCapxulReconcileRequests = (actor = capxulAccountScope) => useRequestMutation(actor, "requests.reconcile", (methods) => methods.requests.reconcile());
|
|
914
|
+
function useCapxulInbox(actor, options) {
|
|
915
|
+
const client = useCapxulClientOrNull();
|
|
916
|
+
return useQuery({
|
|
917
|
+
queryKey: capxulKeys.actorInbox(actor),
|
|
918
|
+
queryFn: async () => {
|
|
919
|
+
const bootstrappedClient = requireBootstrappedClient(client, "inbox.list");
|
|
920
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "inbox.list")).inbox.list(), bootstrappedClient._internal.telemetry);
|
|
921
|
+
},
|
|
922
|
+
enabled: client !== null && actor !== void 0 && (options?.enabled ?? true)
|
|
923
|
+
});
|
|
924
|
+
}
|
|
925
|
+
const useCapxulApproveInboxRequest = (actor = capxulAccountScope) => useRequestMutation(actor, "inbox.approve", (methods, input) => methods.inbox.approve(input), true);
|
|
926
|
+
const useCapxulDeclineInboxRequest = (actor = capxulAccountScope) => useRequestMutation(actor, "inbox.decline", (methods, requestId) => methods.inbox.decline(requestId), true);
|
|
927
|
+
function useCapxulInsightsSummary(actor, options) {
|
|
928
|
+
const client = useCapxulClientOrNull();
|
|
929
|
+
return useQuery({
|
|
930
|
+
queryKey: capxulKeys.actorInsightsSummary(actor),
|
|
931
|
+
queryFn: async () => {
|
|
932
|
+
const bootstrappedClient = requireBootstrappedClient(client, "insights.summary");
|
|
933
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "insights.summary")).insights.summary(), bootstrappedClient._internal.telemetry);
|
|
934
|
+
},
|
|
935
|
+
enabled: client !== null && actor !== void 0 && (options?.enabled ?? true)
|
|
936
|
+
});
|
|
937
|
+
}
|
|
938
|
+
function useCapxulInsightsHistory(actor, options) {
|
|
939
|
+
const client = useCapxulClientOrNull();
|
|
940
|
+
return useQuery({
|
|
941
|
+
queryKey: capxulKeys.actorInsightsHistory(actor),
|
|
942
|
+
queryFn: async () => {
|
|
943
|
+
const bootstrappedClient = requireBootstrappedClient(client, "insights.history");
|
|
944
|
+
return unwrapCapxulResult(await actorMethods(bootstrappedClient, requireActorScope(actor, "insights.history")).insights.history(), bootstrappedClient._internal.telemetry);
|
|
945
|
+
},
|
|
946
|
+
enabled: client !== null && actor !== void 0 && (options?.enabled ?? true)
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
//#endregion
|
|
950
|
+
//#region src/hooks/use-capxul-destinations.ts
|
|
951
|
+
function refKeyForRef(ref) {
|
|
952
|
+
switch (ref.kind) {
|
|
953
|
+
case "handle": return `handle:${ref.handle}`;
|
|
954
|
+
case "email": return `email:${ref.email}`;
|
|
955
|
+
case "orgHandle": return `orgHandle:${ref.orgHandle}`;
|
|
956
|
+
case "capxulUserId": return `capxulUserId:${ref.capxulUserId}`;
|
|
957
|
+
case "payeeId": return `payeeId:${ref.payeeId}`;
|
|
958
|
+
}
|
|
959
|
+
}
|
|
960
|
+
function refCacheKey(input) {
|
|
961
|
+
return input === void 0 ? void 0 : refKeyForRef(input.ref);
|
|
962
|
+
}
|
|
963
|
+
function useCapxulDestinations(input, options) {
|
|
964
|
+
const client = useCapxulClientOrNull();
|
|
965
|
+
return useQuery({
|
|
966
|
+
queryKey: capxulKeys.actorDestinations(input?.actor ?? { kind: "account" }, refCacheKey(input)),
|
|
967
|
+
queryFn: async () => {
|
|
968
|
+
if (input === void 0) throw Errors.invalidInput("ref", "required for destinations.list");
|
|
969
|
+
const bootstrappedClient = requireBootstrappedClient(client, "destinations.list");
|
|
970
|
+
return unwrapCapxulResult(await bootstrappedClient.destinations.list(input), bootstrappedClient._internal.telemetry);
|
|
971
|
+
},
|
|
972
|
+
enabled: client !== null && input !== void 0 && (options?.enabled ?? true)
|
|
973
|
+
});
|
|
974
|
+
}
|
|
975
|
+
function useCapxulAddDestination() {
|
|
976
|
+
const client = useCapxulClientOrNull();
|
|
977
|
+
const queryClient = useQueryClient();
|
|
978
|
+
return useMutation({
|
|
979
|
+
mutationFn: async (input) => {
|
|
980
|
+
const bootstrappedClient = requireBootstrappedClient(client, "destinations.add");
|
|
981
|
+
return unwrapCapxulResult(await bootstrappedClient.destinations.add(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
982
|
+
},
|
|
983
|
+
onSuccess: async (_value, variables) => {
|
|
984
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorDestinationsScope(variables.actor ?? { kind: "account" }) });
|
|
985
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorAddressBook(variables.actor ?? { kind: "account" }) });
|
|
986
|
+
}
|
|
987
|
+
});
|
|
988
|
+
}
|
|
989
|
+
function useCapxulRemoveDestination() {
|
|
990
|
+
const client = useCapxulClientOrNull();
|
|
991
|
+
const queryClient = useQueryClient();
|
|
992
|
+
return useMutation({
|
|
993
|
+
mutationFn: async (input) => {
|
|
994
|
+
const bootstrappedClient = requireBootstrappedClient(client, "destinations.remove");
|
|
995
|
+
return unwrapCapxulResult(await bootstrappedClient.destinations.remove(input), bootstrappedClient._internal.telemetry, "mutation");
|
|
996
|
+
},
|
|
997
|
+
onSuccess: async (_value, variables) => {
|
|
998
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorDestinationsScope(variables.actor ?? { kind: "account" }) });
|
|
999
|
+
}
|
|
1000
|
+
});
|
|
1001
|
+
}
|
|
1002
|
+
//#endregion
|
|
1003
|
+
//#region src/hooks/use-capxul-payroll.ts
|
|
1004
|
+
function useCapxulPayrollRoster(orgId, options) {
|
|
1005
|
+
const client = useCapxulClientOrNull();
|
|
1006
|
+
return useQuery({
|
|
1007
|
+
queryKey: capxulKeys.payrollRoster(orgId),
|
|
1008
|
+
queryFn: async () => {
|
|
1009
|
+
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for payroll.roster.list");
|
|
1010
|
+
const bootstrappedClient = requireBootstrappedClient(client, "payroll.roster.list");
|
|
1011
|
+
return unwrapCapxulResult(await bootstrappedClient.org(orgId).payroll.roster.list(), bootstrappedClient._internal.telemetry);
|
|
1012
|
+
},
|
|
1013
|
+
enabled: client !== null && orgId !== void 0 && (options?.enabled ?? true)
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
function usePayrollMutation(orgId, operation, run) {
|
|
1017
|
+
const client = useCapxulClientOrNull();
|
|
1018
|
+
const queryClient = useQueryClient();
|
|
1019
|
+
return useMutation({
|
|
1020
|
+
mutationFn: async (variables) => {
|
|
1021
|
+
if (orgId === void 0) throw Errors.invalidInput("orgId", `required for ${operation}`);
|
|
1022
|
+
const bootstrappedClient = requireBootstrappedClient(client, operation);
|
|
1023
|
+
return unwrapCapxulResult(await run(bootstrappedClient.org(orgId), variables), bootstrappedClient._internal.telemetry, "mutation");
|
|
1024
|
+
},
|
|
1025
|
+
onSuccess: async (data) => {
|
|
1026
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.payrollRoster(orgId) });
|
|
1027
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsSummary(orgId === void 0 ? void 0 : {
|
|
1028
|
+
kind: "org",
|
|
1029
|
+
orgId
|
|
1030
|
+
}) });
|
|
1031
|
+
await queryClient.invalidateQueries({ queryKey: capxulKeys.actorInsightsHistory(orgId === void 0 ? void 0 : {
|
|
1032
|
+
kind: "org",
|
|
1033
|
+
orgId
|
|
1034
|
+
}) });
|
|
1035
|
+
if (orgId === void 0) return;
|
|
1036
|
+
const actor = {
|
|
1037
|
+
kind: "org",
|
|
1038
|
+
orgId
|
|
1039
|
+
};
|
|
1040
|
+
const payments = paymentsFromValue(data);
|
|
1041
|
+
if (payments.length === 0) return;
|
|
1042
|
+
await Promise.all(payments.map((payment) => invalidateMoneyState(queryClient, {
|
|
1043
|
+
actor,
|
|
1044
|
+
payment,
|
|
1045
|
+
includeAddressBook: true
|
|
1046
|
+
})));
|
|
1047
|
+
}
|
|
1048
|
+
});
|
|
1049
|
+
}
|
|
1050
|
+
const useCapxulAddPayrollRosterLine = (orgId) => usePayrollMutation(orgId, "payroll.roster.add", (org, input) => org.payroll.roster.add(input));
|
|
1051
|
+
const useCapxulUpdatePayrollRosterLine = (orgId) => usePayrollMutation(orgId, "payroll.roster.update", (org, variables) => org.payroll.roster.update(variables.rosterLineId, variables.input));
|
|
1052
|
+
const useCapxulRemovePayrollRosterLine = (orgId) => usePayrollMutation(orgId, "payroll.roster.remove", (org, rosterLineId) => org.payroll.roster.remove(rosterLineId));
|
|
1053
|
+
const useCapxulRunPayroll = (orgId) => usePayrollMutation(orgId, "payroll.run", (org, input) => org.payroll.run(input));
|
|
1054
|
+
//#endregion
|
|
368
1055
|
//#region src/hooks/use-capxul-orgs.ts
|
|
369
1056
|
function useCapxulOrgs(options) {
|
|
370
|
-
const client =
|
|
1057
|
+
const client = useCapxulClientOrNull();
|
|
371
1058
|
return useQuery({
|
|
372
1059
|
queryKey: capxulKeys.orgs,
|
|
373
|
-
queryFn: async () =>
|
|
374
|
-
|
|
1060
|
+
queryFn: async () => {
|
|
1061
|
+
const bootstrappedClient = requireBootstrappedClient(client, "orgs");
|
|
1062
|
+
return unwrapCapxulResult(await bootstrappedClient.orgs(), bootstrappedClient._internal.telemetry);
|
|
1063
|
+
},
|
|
1064
|
+
enabled: client !== null && (options?.enabled ?? true)
|
|
375
1065
|
});
|
|
376
1066
|
}
|
|
377
1067
|
//#endregion
|
|
@@ -382,7 +1072,7 @@ function useCapxulOrg(orgId, options) {
|
|
|
382
1072
|
queryKey: capxulKeys.org(orgId),
|
|
383
1073
|
queryFn: async () => {
|
|
384
1074
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrg");
|
|
385
|
-
return unwrapCapxulResult(await client.orgs()).find((org) => org.id === orgId) ?? null;
|
|
1075
|
+
return unwrapCapxulResult(await client.orgs(), client._internal.telemetry).find((org) => org.id === orgId) ?? null;
|
|
386
1076
|
},
|
|
387
1077
|
enabled: (options?.enabled ?? true) && orgId !== void 0
|
|
388
1078
|
});
|
|
@@ -395,7 +1085,7 @@ function useCapxulOrgMembers(orgId, options) {
|
|
|
395
1085
|
queryKey: capxulKeys.orgMembers(orgId),
|
|
396
1086
|
queryFn: async () => {
|
|
397
1087
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgMembers");
|
|
398
|
-
return unwrapCapxulResult(await client.org(orgId).members());
|
|
1088
|
+
return unwrapCapxulResult(await client.org(orgId).members(), client._internal.telemetry);
|
|
399
1089
|
},
|
|
400
1090
|
enabled: (options?.enabled ?? true) && orgId !== void 0
|
|
401
1091
|
});
|
|
@@ -408,7 +1098,7 @@ function useCapxulOrgRoles(orgId, options) {
|
|
|
408
1098
|
queryKey: capxulKeys.orgRoles(orgId),
|
|
409
1099
|
queryFn: async () => {
|
|
410
1100
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgRoles");
|
|
411
|
-
return unwrapCapxulResult(await client.org(orgId).roles());
|
|
1101
|
+
return unwrapCapxulResult(await client.org(orgId).roles(), client._internal.telemetry);
|
|
412
1102
|
},
|
|
413
1103
|
enabled: (options?.enabled ?? true) && orgId !== void 0
|
|
414
1104
|
});
|
|
@@ -420,7 +1110,7 @@ function useCapxulOrgDeployRoles() {
|
|
|
420
1110
|
const queryClient = useQueryClient();
|
|
421
1111
|
return useMutation({
|
|
422
1112
|
mutationFn: async (orgId) => {
|
|
423
|
-
return unwrapCapxulResult(await client.org(orgId).deployRoles());
|
|
1113
|
+
return unwrapCapxulResult(await client.org(orgId).deployRoles(), client._internal.telemetry, "mutation");
|
|
424
1114
|
},
|
|
425
1115
|
onSuccess: async (_roles, orgId) => {
|
|
426
1116
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.orgRoles(orgId) });
|
|
@@ -437,7 +1127,7 @@ function useCapxulOrgTreasury(orgId, options) {
|
|
|
437
1127
|
queryKey: capxulKeys.orgTreasury(orgId),
|
|
438
1128
|
queryFn: async () => {
|
|
439
1129
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulOrgTreasury");
|
|
440
|
-
return unwrapCapxulResult(await client.org(orgId).treasury());
|
|
1130
|
+
return unwrapCapxulResult(await client.org(orgId).treasury(), client._internal.telemetry);
|
|
441
1131
|
},
|
|
442
1132
|
enabled: (options?.enabled ?? true) && orgId !== void 0
|
|
443
1133
|
});
|
|
@@ -448,13 +1138,41 @@ function useCapxulCreateOrg() {
|
|
|
448
1138
|
const client = useCapxulClient();
|
|
449
1139
|
const queryClient = useQueryClient();
|
|
450
1140
|
return useMutation({
|
|
451
|
-
mutationFn: async (input) => unwrapCapxulResult(await client.createOrg(input)),
|
|
1141
|
+
mutationFn: async (input) => unwrapCapxulResult(await client.createOrg(input), client._internal.telemetry, "mutation"),
|
|
452
1142
|
onSuccess: async () => {
|
|
453
1143
|
await queryClient.invalidateQueries({ queryKey: capxulKeys.orgs });
|
|
454
1144
|
}
|
|
455
1145
|
});
|
|
456
1146
|
}
|
|
457
1147
|
//#endregion
|
|
1148
|
+
//#region src/hooks/use-capxul-complete-personal-onboarding.ts
|
|
1149
|
+
function useCapxulCompletePersonalOnboarding() {
|
|
1150
|
+
const client = useCapxulClient();
|
|
1151
|
+
const queryClient = useQueryClient();
|
|
1152
|
+
return useMutation({
|
|
1153
|
+
mutationFn: async (input) => unwrapCapxulResult(await client.onboarding.completePersonal(input), client._internal.telemetry, "mutation"),
|
|
1154
|
+
onSuccess: async () => {
|
|
1155
|
+
await Promise.all([queryClient.invalidateQueries({ queryKey: capxulKeys.profile }), queryClient.invalidateQueries({ queryKey: capxulKeys.accountLifecycle })]);
|
|
1156
|
+
}
|
|
1157
|
+
});
|
|
1158
|
+
}
|
|
1159
|
+
//#endregion
|
|
1160
|
+
//#region src/hooks/use-capxul-complete-organization-onboarding.ts
|
|
1161
|
+
function useCapxulCompleteOrganizationOnboarding() {
|
|
1162
|
+
const client = useCapxulClient();
|
|
1163
|
+
const queryClient = useQueryClient();
|
|
1164
|
+
return useMutation({
|
|
1165
|
+
mutationFn: async (input) => unwrapCapxulResult(await client.onboarding.completeOrganization(input), client._internal.telemetry, "mutation"),
|
|
1166
|
+
onSuccess: async () => {
|
|
1167
|
+
await Promise.all([
|
|
1168
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.profile }),
|
|
1169
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.accountLifecycle }),
|
|
1170
|
+
queryClient.invalidateQueries({ queryKey: capxulKeys.orgs })
|
|
1171
|
+
]);
|
|
1172
|
+
}
|
|
1173
|
+
});
|
|
1174
|
+
}
|
|
1175
|
+
//#endregion
|
|
458
1176
|
//#region src/hooks/use-capxul-invite-member.ts
|
|
459
1177
|
function useCapxulInviteMember(orgId) {
|
|
460
1178
|
const client = useCapxulClient();
|
|
@@ -462,7 +1180,7 @@ function useCapxulInviteMember(orgId) {
|
|
|
462
1180
|
return useMutation({
|
|
463
1181
|
mutationFn: async (input) => {
|
|
464
1182
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulInviteMember");
|
|
465
|
-
return unwrapCapxulResult(await client.org(orgId).invite(input));
|
|
1183
|
+
return unwrapCapxulResult(await client.org(orgId).invite(input), client._internal.telemetry, "mutation");
|
|
466
1184
|
},
|
|
467
1185
|
onSuccess: async () => {
|
|
468
1186
|
if (orgId === void 0) return;
|
|
@@ -478,7 +1196,7 @@ function useCapxulRemoveMember(orgId) {
|
|
|
478
1196
|
return useMutation({
|
|
479
1197
|
mutationFn: async (input) => {
|
|
480
1198
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulRemoveMember");
|
|
481
|
-
return unwrapCapxulResult(await client.org(orgId).removeMember(input));
|
|
1199
|
+
return unwrapCapxulResult(await client.org(orgId).removeMember(input), client._internal.telemetry, "mutation");
|
|
482
1200
|
},
|
|
483
1201
|
onSuccess: async () => {
|
|
484
1202
|
if (orgId === void 0) return;
|
|
@@ -494,7 +1212,7 @@ function useCapxulAssignRole(orgId) {
|
|
|
494
1212
|
return useMutation({
|
|
495
1213
|
mutationFn: async (input) => {
|
|
496
1214
|
if (orgId === void 0) throw Errors.invalidInput("orgId", "required for useCapxulAssignRole");
|
|
497
|
-
return unwrapCapxulResult(await client.org(orgId).assignRole(input));
|
|
1215
|
+
return unwrapCapxulResult(await client.org(orgId).assignRole(input), client._internal.telemetry, "mutation");
|
|
498
1216
|
},
|
|
499
1217
|
onSuccess: async () => {
|
|
500
1218
|
if (orgId === void 0) return;
|
|
@@ -503,22 +1221,265 @@ function useCapxulAssignRole(orgId) {
|
|
|
503
1221
|
});
|
|
504
1222
|
}
|
|
505
1223
|
//#endregion
|
|
506
|
-
//#region src/hooks/use-capxul-
|
|
507
|
-
function
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
1224
|
+
//#region src/hooks/use-capxul-switch-acting-entity.ts
|
|
1225
|
+
function useCapxulSwitchActingEntity() {
|
|
1226
|
+
return useMutation({ mutationFn: async (_input) => void 0 });
|
|
1227
|
+
}
|
|
1228
|
+
//#endregion
|
|
1229
|
+
//#region src/headless/shared/headless-error-view.ts
|
|
1230
|
+
const FAILURE_MODES = new Set([
|
|
1231
|
+
"auth-origin-mismatch",
|
|
1232
|
+
"stale-openfort-cache",
|
|
1233
|
+
"app-env-allowlist",
|
|
1234
|
+
"no-secure-context",
|
|
1235
|
+
"unknown"
|
|
1236
|
+
]);
|
|
1237
|
+
function isFailureMode(value) {
|
|
1238
|
+
return typeof value === "string" && FAILURE_MODES.has(value);
|
|
1239
|
+
}
|
|
1240
|
+
function getFailureMode(error) {
|
|
1241
|
+
const candidate = error.details?.failure_mode;
|
|
1242
|
+
return isFailureMode(candidate) ? candidate : void 0;
|
|
1243
|
+
}
|
|
1244
|
+
const FAILURE_USER_MESSAGES = {
|
|
1245
|
+
"auth-origin-mismatch": "Your sign-in session is not visible to the wallet. Sign out and sign in again.",
|
|
1246
|
+
"stale-openfort-cache": "Stale wallet data from a previous session is blocking setup. Sign out, then sign in with your current email.",
|
|
1247
|
+
"app-env-allowlist": "This app origin is not authorized for the publishable key. Check configuration.",
|
|
1248
|
+
"no-secure-context": "Your browser cannot access secure wallet features. Open the app in a standard browser window.",
|
|
1249
|
+
unknown: "Something went wrong setting up your wallet. Try again or sign out and sign in."
|
|
1250
|
+
};
|
|
1251
|
+
const FAILURE_SUGGESTED_ACTIONS = {
|
|
1252
|
+
"auth-origin-mismatch": "sign_out_and_in",
|
|
1253
|
+
"stale-openfort-cache": "sign_out_and_in",
|
|
1254
|
+
"app-env-allowlist": "check_configuration",
|
|
1255
|
+
"no-secure-context": "check_configuration",
|
|
1256
|
+
unknown: "retry"
|
|
1257
|
+
};
|
|
1258
|
+
const FAILURE_RECOVERABLE = {
|
|
1259
|
+
"auth-origin-mismatch": false,
|
|
1260
|
+
"stale-openfort-cache": true,
|
|
1261
|
+
"app-env-allowlist": false,
|
|
1262
|
+
"no-secure-context": false,
|
|
1263
|
+
unknown: true
|
|
1264
|
+
};
|
|
1265
|
+
function coerceToCapxulError(cause) {
|
|
1266
|
+
if (isCapxulError(cause)) return cause;
|
|
1267
|
+
if (cause instanceof Error) return Errors.unknown(cause);
|
|
1268
|
+
return Errors.unknown(String(cause));
|
|
1269
|
+
}
|
|
1270
|
+
function toHeadlessErrorView(error) {
|
|
1271
|
+
const failureMode = getFailureMode(error);
|
|
1272
|
+
const suggestedAction = failureMode ? FAILURE_SUGGESTED_ACTIONS[failureMode] : defaultSuggestedAction(error);
|
|
1273
|
+
const userMessage = failureMode ? FAILURE_USER_MESSAGES[failureMode] : defaultUserMessage(error);
|
|
1274
|
+
const recoverable = failureMode ? FAILURE_RECOVERABLE[failureMode] : defaultRecoverable(error);
|
|
1275
|
+
return {
|
|
1276
|
+
code: error.code,
|
|
1277
|
+
failureMode,
|
|
1278
|
+
userMessage,
|
|
1279
|
+
suggestedAction,
|
|
1280
|
+
recoverable,
|
|
1281
|
+
diagnostics: buildDiagnostics(error, failureMode),
|
|
1282
|
+
correlationId: error.correlationId
|
|
1283
|
+
};
|
|
1284
|
+
}
|
|
1285
|
+
function defaultUserMessage(error) {
|
|
1286
|
+
if (error.code === "OTP_EXPIRED") return "Verification code has expired. Request a new one.";
|
|
1287
|
+
if (error.code === "NOT_AUTHENTICATED") return "You are not signed in. Sign in and try again.";
|
|
1288
|
+
if (error.code === "RATE_LIMITED") return "Too many attempts. Wait a moment and try again.";
|
|
1289
|
+
if (error.code === "NETWORK_ERROR") return "Network error. Check your connection and try again.";
|
|
1290
|
+
return error.message;
|
|
1291
|
+
}
|
|
1292
|
+
function defaultSuggestedAction(error) {
|
|
1293
|
+
switch (error.code) {
|
|
1294
|
+
case "NOT_AUTHENTICATED":
|
|
1295
|
+
case "OTP_EXPIRED":
|
|
1296
|
+
case "WRONG_STATE": return "sign_out_and_in";
|
|
1297
|
+
case "ENV_MISSING": return "check_configuration";
|
|
1298
|
+
case "RATE_LIMITED":
|
|
1299
|
+
case "NETWORK_ERROR":
|
|
1300
|
+
case "PROVIDER_ERROR":
|
|
1301
|
+
case "TRANSACTION_FAILED": return "retry";
|
|
1302
|
+
default: return "contact_support";
|
|
1303
|
+
}
|
|
1304
|
+
}
|
|
1305
|
+
function defaultRecoverable(error) {
|
|
1306
|
+
switch (error.code) {
|
|
1307
|
+
case "ENV_MISSING":
|
|
1308
|
+
case "NOT_IMPLEMENTED": return false;
|
|
1309
|
+
default: return true;
|
|
1310
|
+
}
|
|
1311
|
+
}
|
|
1312
|
+
function buildDiagnostics(error, failureMode) {
|
|
1313
|
+
const parts = [`code=${error.code}`];
|
|
1314
|
+
if (failureMode !== void 0) parts.push(`failure_mode=${failureMode}`);
|
|
1315
|
+
if (error.layer !== void 0) parts.push(`layer=${error.layer}`);
|
|
1316
|
+
const provider = error.details?.provider;
|
|
1317
|
+
if (typeof provider === "string") parts.push(`provider=${provider}`);
|
|
1318
|
+
const operation = error.details?.operation;
|
|
1319
|
+
if (typeof operation === "string") parts.push(`operation=${operation}`);
|
|
1320
|
+
return parts.join(" ");
|
|
1321
|
+
}
|
|
1322
|
+
//#endregion
|
|
1323
|
+
//#region src/headless/shared/types.ts
|
|
1324
|
+
function toQuerySlotState(query) {
|
|
1325
|
+
return {
|
|
1326
|
+
data: query.data,
|
|
1327
|
+
isLoading: query.isLoading,
|
|
1328
|
+
isFetching: query.isFetching,
|
|
1329
|
+
isError: query.isError,
|
|
1330
|
+
error: query.error === null ? null : toHeadlessErrorView(query.error)
|
|
1331
|
+
};
|
|
1332
|
+
}
|
|
1333
|
+
//#endregion
|
|
1334
|
+
//#region ../types/src/index.ts
|
|
1335
|
+
const SUPPORTED_CURRENCIES = [
|
|
1336
|
+
{
|
|
1337
|
+
code: "USD",
|
|
1338
|
+
symbol: "$",
|
|
1339
|
+
name: "US Dollar"
|
|
1340
|
+
},
|
|
1341
|
+
{
|
|
1342
|
+
code: "NGN",
|
|
1343
|
+
symbol: "NGN",
|
|
1344
|
+
name: "Nigerian Naira"
|
|
1345
|
+
},
|
|
1346
|
+
{
|
|
1347
|
+
code: "GHS",
|
|
1348
|
+
symbol: "GHS",
|
|
1349
|
+
name: "Ghanaian Cedi"
|
|
1350
|
+
},
|
|
1351
|
+
{
|
|
1352
|
+
code: "KES",
|
|
1353
|
+
symbol: "KSh",
|
|
1354
|
+
name: "Kenyan Shilling"
|
|
1355
|
+
},
|
|
1356
|
+
{
|
|
1357
|
+
code: "UGX",
|
|
1358
|
+
symbol: "USh",
|
|
1359
|
+
name: "Ugandan Shilling"
|
|
1360
|
+
}
|
|
1361
|
+
];
|
|
1362
|
+
SUPPORTED_CURRENCIES.map((currency) => currency.code);
|
|
1363
|
+
Object.fromEntries(SUPPORTED_CURRENCIES.map((currency) => [currency.code, currency.symbol]));
|
|
1364
|
+
Math.floor(Number.MAX_SAFE_INTEGER / 1e3);
|
|
1365
|
+
//#endregion
|
|
1366
|
+
//#region src/headless/money/SendMoney.tsx
|
|
1367
|
+
function SendMoney({ initialValue = null, slots, onSent }) {
|
|
1368
|
+
const pay = useCapxulPay();
|
|
1369
|
+
const [value, setValue] = useState(initialValue);
|
|
1370
|
+
const [error, setError] = useState(null);
|
|
1371
|
+
const submit = async () => {
|
|
1372
|
+
setError(null);
|
|
1373
|
+
if (value === null) return;
|
|
1374
|
+
try {
|
|
1375
|
+
await pay.mutateAsync(value);
|
|
1376
|
+
onSent?.();
|
|
1377
|
+
} catch (cause) {
|
|
1378
|
+
setError(toHeadlessErrorView(coerceToCapxulError(cause)));
|
|
518
1379
|
}
|
|
1380
|
+
};
|
|
1381
|
+
const slot = slots.form?.({
|
|
1382
|
+
value,
|
|
1383
|
+
setValue,
|
|
1384
|
+
submit: () => void submit(),
|
|
1385
|
+
pending: pay.isPending,
|
|
1386
|
+
disabled: pay.isPending || value === null,
|
|
1387
|
+
succeeded: pay.isSuccess,
|
|
1388
|
+
error
|
|
519
1389
|
});
|
|
1390
|
+
const children = /* @__PURE__ */ jsxs(Fragment, { children: [slot, error === null ? null : slots.error?.(error)] });
|
|
1391
|
+
return slots.root?.({ children }) ?? children;
|
|
1392
|
+
}
|
|
1393
|
+
//#endregion
|
|
1394
|
+
//#region src/headless/relationship/AddressBook.tsx
|
|
1395
|
+
function AddressBook(props) {
|
|
1396
|
+
const { slots } = props;
|
|
1397
|
+
const actor = "actor" in props ? props.actor : capxulAccountScope;
|
|
1398
|
+
const entries = useCapxulAddressBook(actor);
|
|
1399
|
+
const add = useCapxulAddAddressBookEntry(actor);
|
|
1400
|
+
const hide = useCapxulHideAddressBookEntry(actor);
|
|
1401
|
+
const unhide = useCapxulUnhideAddressBookEntry(actor);
|
|
1402
|
+
const label = useCapxulLabelAddressBookEntry(actor);
|
|
1403
|
+
const pending = add.isPending || hide.isPending || unhide.isPending || label.isPending;
|
|
1404
|
+
const children = /* @__PURE__ */ jsxs(Fragment, { children: [slots.entries?.(toQuerySlotState(entries)), slots.actions?.({
|
|
1405
|
+
add: (input) => add.mutateAsync(input),
|
|
1406
|
+
hide: (entryId) => hide.mutateAsync(entryId),
|
|
1407
|
+
unhide: (entryId) => unhide.mutateAsync(entryId),
|
|
1408
|
+
label: (input) => label.mutateAsync(input),
|
|
1409
|
+
pending,
|
|
1410
|
+
disabled: pending || actor === void 0
|
|
1411
|
+
})] });
|
|
1412
|
+
return slots.root?.({ children }) ?? children;
|
|
1413
|
+
}
|
|
1414
|
+
//#endregion
|
|
1415
|
+
//#region src/headless/relationship/RequestInbox.tsx
|
|
1416
|
+
function RequestInbox(props) {
|
|
1417
|
+
const { slots } = props;
|
|
1418
|
+
const actor = "actor" in props ? props.actor : capxulAccountScope;
|
|
1419
|
+
const requests = useCapxulRequests(actor);
|
|
1420
|
+
const inbox = useCapxulInbox(actor);
|
|
1421
|
+
const issue = useCapxulIssueRequest(actor);
|
|
1422
|
+
const cancel = useCapxulCancelRequest(actor);
|
|
1423
|
+
const approve = useCapxulApproveInboxRequest(actor);
|
|
1424
|
+
const decline = useCapxulDeclineInboxRequest(actor);
|
|
1425
|
+
const pending = issue.isPending || cancel.isPending || approve.isPending || decline.isPending;
|
|
1426
|
+
const children = /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
1427
|
+
slots.requests?.(toQuerySlotState(requests)),
|
|
1428
|
+
slots.inbox?.(toQuerySlotState(inbox)),
|
|
1429
|
+
slots.actions?.({
|
|
1430
|
+
issue: (input) => issue.mutateAsync(input),
|
|
1431
|
+
cancel: (requestId) => cancel.mutateAsync(requestId),
|
|
1432
|
+
approve: (input) => approve.mutateAsync(input),
|
|
1433
|
+
decline: (requestId) => decline.mutateAsync(requestId),
|
|
1434
|
+
pending,
|
|
1435
|
+
disabled: pending || actor === void 0
|
|
1436
|
+
})
|
|
1437
|
+
] });
|
|
1438
|
+
return slots.root?.({ children }) ?? children;
|
|
1439
|
+
}
|
|
1440
|
+
//#endregion
|
|
1441
|
+
//#region src/headless/relationship/InsightsSummary.tsx
|
|
1442
|
+
function InsightsSummary(props) {
|
|
1443
|
+
const { slots } = props;
|
|
1444
|
+
const summary = useCapxulInsightsSummary("actor" in props ? props.actor : capxulAccountScope);
|
|
1445
|
+
const children = slots.summary?.(toQuerySlotState(summary));
|
|
1446
|
+
return slots.root?.({ children }) ?? children;
|
|
1447
|
+
}
|
|
1448
|
+
//#endregion
|
|
1449
|
+
//#region src/headless/relationship/PayrollRoster.tsx
|
|
1450
|
+
function PayrollRoster({ orgId, slots }) {
|
|
1451
|
+
const roster = useCapxulPayrollRoster(orgId);
|
|
1452
|
+
const add = useCapxulAddPayrollRosterLine(orgId);
|
|
1453
|
+
const update = useCapxulUpdatePayrollRosterLine(orgId);
|
|
1454
|
+
const remove = useCapxulRemovePayrollRosterLine(orgId);
|
|
1455
|
+
const run = useCapxulRunPayroll(orgId);
|
|
1456
|
+
const pending = add.isPending || update.isPending || remove.isPending || run.isPending;
|
|
1457
|
+
const children = /* @__PURE__ */ jsxs(Fragment, { children: [slots.roster?.(toQuerySlotState(roster)), slots.actions?.({
|
|
1458
|
+
add: (input) => add.mutateAsync(input),
|
|
1459
|
+
update: (input) => update.mutateAsync(input),
|
|
1460
|
+
remove: (rosterLineId) => remove.mutateAsync(rosterLineId),
|
|
1461
|
+
run: (input) => run.mutateAsync(input),
|
|
1462
|
+
pending,
|
|
1463
|
+
disabled: pending
|
|
1464
|
+
})] });
|
|
1465
|
+
return slots.root?.({ children }) ?? children;
|
|
1466
|
+
}
|
|
1467
|
+
//#endregion
|
|
1468
|
+
//#region src/headless/relationship/Destinations.tsx
|
|
1469
|
+
function Destinations({ input, slots }) {
|
|
1470
|
+
const destinations = useCapxulDestinations(input);
|
|
1471
|
+
const add = useCapxulAddDestination();
|
|
1472
|
+
const remove = useCapxulRemoveDestination();
|
|
1473
|
+
const pending = add.isPending || remove.isPending;
|
|
1474
|
+
const children = /* @__PURE__ */ jsxs(Fragment, { children: [slots.destinations?.(toQuerySlotState(destinations)), slots.actions?.({
|
|
1475
|
+
add: (value) => add.mutateAsync(value),
|
|
1476
|
+
remove: (value) => remove.mutateAsync(value),
|
|
1477
|
+
pending,
|
|
1478
|
+
disabled: pending
|
|
1479
|
+
})] });
|
|
1480
|
+
return slots.root?.({ children }) ?? children;
|
|
520
1481
|
}
|
|
521
1482
|
//#endregion
|
|
522
|
-
export { CapxulProvider,
|
|
1483
|
+
export { AddressBook, CapxulProvider, Destinations, InsightsSummary, PayrollRoster, RequestInbox, SendMoney, capxulAccountScope, capxulOrgScope, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulAccountLifecycle, useCapxulAddAddressBookEntry, useCapxulAddDestination, useCapxulAddPayrollRosterLine, useCapxulAddressBook, useCapxulAddressBookEntry, useCapxulApproveInboxRequest, useCapxulAssignRole, useCapxulCancelRequest, useCapxulClientOrNull, useCapxulCompleteOrganizationOnboarding, useCapxulCompletePersonalOnboarding, useCapxulCreateOrg, useCapxulDeclineInboxRequest, useCapxulDestinations, useCapxulHideAddressBookEntry, useCapxulInbox, useCapxulInsightsHistory, useCapxulInsightsSummary, useCapxulInviteMember, useCapxulIssueRequest, useCapxulLabelAddressBookEntry, useCapxulOrg, useCapxulOrgDeployRoles, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPayout, useCapxulPayrollRoster, useCapxulProfile, useCapxulReconcileRequests, useCapxulRemoveDestination, useCapxulRemoveMember, useCapxulRemovePayrollRosterLine, useCapxulRequest, useCapxulRequests, useCapxulRunPayroll, useCapxulSession, useCapxulSignIn, useCapxulSignOut, useCapxulSubAccountCreate, useCapxulSubAccountDelete, useCapxulSubAccountRename, useCapxulSubAccountsList, useCapxulSwitchActingEntity, useCapxulTransfer, useCapxulUnhideAddressBookEntry, useCapxulUpdatePayrollRosterLine, useCapxulVerifyOtp, useCapxulWithdraw };
|
|
523
1484
|
|
|
524
1485
|
//# sourceMappingURL=index.mjs.map
|