@capxul/sdk-react 4.1.4 → 4.2.0-rc.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/README.md +6 -4
- package/dist/capxul-source.json +11 -0
- package/dist/{controllers-DIf8elqQ.d.mts → controllers-BWmKRFy6.d.mts} +6 -0
- package/dist/{controllers-Dzk5AvfL.mjs → controllers-DaT-AGx6.mjs} +146 -15
- package/dist/index.d.mts +46 -10
- package/dist/index.mjs +88 -26
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.mjs +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -28,10 +28,12 @@ export function Providers({ children }: { children: React.ReactNode }) {
|
|
|
28
28
|
session. Account and Organization readiness transitions refresh active
|
|
29
29
|
authenticated queries.
|
|
30
30
|
- `CapxulAuthenticationController` and `CapxulOnboardingController` select
|
|
31
|
-
app-owned slots and render no SDK-owned DOM.
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
31
|
+
app-owned slots and render no SDK-owned DOM. The onboarding controller keeps
|
|
32
|
+
no Organization submission: after a reload the Core SDK reads the pending
|
|
33
|
+
Organization from the backend and attaches it, so the app re-submits nothing.
|
|
34
|
+
A claimed identity with no Organization and no app-held form step reports
|
|
35
|
+
`organizationProgress` with `{ at: "loading", orgId: null }` until that
|
|
36
|
+
attach lands.
|
|
35
37
|
- Rich-data hooks such as `useCapxulProfile`, `useCapxulOrgs`, members, roles,
|
|
36
38
|
treasury, and money hooks remain TanStack Query projections. Personal
|
|
37
39
|
holdings and activity reads start only after the Account is claimed.
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
{
|
|
2
|
+
"source": {
|
|
3
|
+
"commit": "a7e55e5f1c2af5567a8b285a4ef70b8b5a3289f6",
|
|
4
|
+
"tree": "91bf1b080c0006fe30131711c13c843afd627158",
|
|
5
|
+
"branch": "codex/programme-rc",
|
|
6
|
+
"repository": "https://github.com/Xelmar-tech/infrastructure",
|
|
7
|
+
"lockfileSha256": "5870f53b72706d103220c1bcf733cb4fb71196aea32a9cfbdc277d73cc959264"
|
|
8
|
+
},
|
|
9
|
+
"name": "@capxul/sdk-react",
|
|
10
|
+
"version": "4.2.0-rc.10"
|
|
11
|
+
}
|
|
@@ -25,6 +25,12 @@ interface OrganizationDetails {
|
|
|
25
25
|
readonly country: string;
|
|
26
26
|
readonly bio?: string;
|
|
27
27
|
readonly size?: string;
|
|
28
|
+
/**
|
|
29
|
+
* #1955: the storage id `useCapxulUploadImage` handed back on file pick. The
|
|
30
|
+
* create call carries it, so the backend records the logo on the `orgs`
|
|
31
|
+
* insert instead of the app binding it afterwards.
|
|
32
|
+
*/
|
|
33
|
+
readonly logoStorageId?: string;
|
|
28
34
|
}
|
|
29
35
|
interface CreateOrganizationSubmission {
|
|
30
36
|
readonly profileDetails: ProfileDetails;
|
|
@@ -151,10 +151,35 @@ const capxulKeys = {
|
|
|
151
151
|
]
|
|
152
152
|
};
|
|
153
153
|
//#endregion
|
|
154
|
-
//#region src/
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
154
|
+
//#region src/internal/invocation-controls.ts
|
|
155
|
+
/**
|
|
156
|
+
* Keep only the five public option fields, and only when they hold the right
|
|
157
|
+
* kind of value. A named action verb takes its attempt as an optional FIRST
|
|
158
|
+
* argument, so a screen that wires one straight to a DOM handler
|
|
159
|
+
* (`onClick={row.hide}`) hands us a React SyntheticEvent. That is not an
|
|
160
|
+
* attempt: it must reach neither the SDK call nor the callback echo.
|
|
161
|
+
*/
|
|
162
|
+
function toInvocationOptions(options) {
|
|
163
|
+
if (typeof options !== "object" || options === null) return void 0;
|
|
164
|
+
const attempt = {};
|
|
165
|
+
if (typeof options.correlationId === "string") attempt.correlationId = options.correlationId;
|
|
166
|
+
if (typeof options.journeyId === "string") attempt.journeyId = options.journeyId;
|
|
167
|
+
if (typeof options.timeoutMs === "number") attempt.timeoutMs = options.timeoutMs;
|
|
168
|
+
if (typeof options.deadlineMs === "number") attempt.deadlineMs = options.deadlineMs;
|
|
169
|
+
if (options.signal instanceof AbortSignal) attempt.signal = options.signal;
|
|
170
|
+
return Object.keys(attempt).length === 0 ? void 0 : attempt;
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Map the public camel-case invocation options onto the Core SDK's control
|
|
174
|
+
* spelling. ONE definition, because the identity facade and every headless
|
|
175
|
+
* engine must hand the SDK the same shape: a caller that captured one user
|
|
176
|
+
* attempt before it started gets that attempt's `correlation_id`/`journey_id`
|
|
177
|
+
* on whichever operation it starts (#1960 R02).
|
|
178
|
+
*
|
|
179
|
+
* It creates no identifiers. An absent option stays absent, so an automatic
|
|
180
|
+
* read keeps its own invocation context instead of borrowing an attempt's.
|
|
181
|
+
*/
|
|
182
|
+
function toInvocationControls(options) {
|
|
158
183
|
if (options === void 0) return void 0;
|
|
159
184
|
return {
|
|
160
185
|
...options.signal === void 0 ? {} : { signal: options.signal },
|
|
@@ -164,12 +189,16 @@ function controls(options) {
|
|
|
164
189
|
...options.journeyId === void 0 ? {} : { journey_id: options.journeyId }
|
|
165
190
|
};
|
|
166
191
|
}
|
|
192
|
+
//#endregion
|
|
193
|
+
//#region src/identity.tsx
|
|
194
|
+
const MISSING_IDENTITY_PROVIDER = Symbol("MISSING_IDENTITY_PROVIDER");
|
|
195
|
+
const IdentityContext = createContext(MISSING_IDENTITY_PROVIDER);
|
|
167
196
|
const failure = (result) => result.ok ? null : {
|
|
168
197
|
ok: false,
|
|
169
198
|
reason: result.refused
|
|
170
199
|
};
|
|
171
200
|
async function guarded(runtime, verb, options, run) {
|
|
172
|
-
const invocation =
|
|
201
|
+
const invocation = toInvocationControls(options);
|
|
173
202
|
try {
|
|
174
203
|
return await (runtime.runFacade?.(verb, invocation, run) ?? run(invocation));
|
|
175
204
|
} catch {
|
|
@@ -201,30 +230,116 @@ function normalizeOrganization(organization) {
|
|
|
201
230
|
if (name.length === 0) return null;
|
|
202
231
|
if (organization.bio !== void 0 && typeof organization.bio !== "string") return null;
|
|
203
232
|
if (organization.size !== void 0 && typeof organization.size !== "string") return null;
|
|
233
|
+
if (organization.logoStorageId !== void 0 && (typeof organization.logoStorageId !== "string" || organization.logoStorageId.length === 0)) return null;
|
|
204
234
|
try {
|
|
205
235
|
return {
|
|
206
236
|
name,
|
|
207
237
|
handle: toHandle(handle),
|
|
208
238
|
country: toCountryCode(organization.country),
|
|
209
239
|
...organization.bio === void 0 ? {} : { bio: organization.bio },
|
|
210
|
-
...organization.size === void 0 ? {} : { size: organization.size }
|
|
240
|
+
...organization.size === void 0 ? {} : { size: organization.size },
|
|
241
|
+
...organization.logoStorageId === void 0 ? {} : { logoStorageId: organization.logoStorageId }
|
|
211
242
|
};
|
|
212
243
|
} catch {
|
|
213
244
|
return null;
|
|
214
245
|
}
|
|
215
246
|
}
|
|
247
|
+
/** The Organization id when its lane is already running or finished, else null. */
|
|
248
|
+
const runningOrganization = (state) => {
|
|
249
|
+
if (state.phase !== "authenticated" || state.account.at !== "claimed") return null;
|
|
250
|
+
const org = state.account.org;
|
|
251
|
+
return org !== null && (org.at === "loading" || org.at === "settingUp" || org.at === "ready") ? org.orgId : null;
|
|
252
|
+
};
|
|
253
|
+
/** A superseded session read waits at most this long for the winning read. */
|
|
254
|
+
const SESSION_SETTLE_LIMIT_MS = 3e4;
|
|
255
|
+
const accountInFlight = (state) => state.phase === "authenticated" && (state.account.at === "deriving" || state.account.at === "claiming");
|
|
216
256
|
function createAuth(client, clearAuthenticatedQueries) {
|
|
217
257
|
const runtime = client._internal.identity;
|
|
258
|
+
const settledSession = (invocation) => new Promise((resolve) => {
|
|
259
|
+
let done = false;
|
|
260
|
+
let stop = null;
|
|
261
|
+
let timer = null;
|
|
262
|
+
const onAbort = () => finish({
|
|
263
|
+
ok: false,
|
|
264
|
+
reason: "CANCELLED"
|
|
265
|
+
});
|
|
266
|
+
const finish = (result) => {
|
|
267
|
+
if (done) return;
|
|
268
|
+
done = true;
|
|
269
|
+
stop?.();
|
|
270
|
+
if (timer !== null) clearTimeout(timer);
|
|
271
|
+
invocation?.signal?.removeEventListener("abort", onAbort);
|
|
272
|
+
resolve(result);
|
|
273
|
+
};
|
|
274
|
+
if (invocation?.signal?.aborted) {
|
|
275
|
+
onAbort();
|
|
276
|
+
return;
|
|
277
|
+
}
|
|
278
|
+
invocation?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
279
|
+
const unsubscribe = runtime.subscribeTransitions((record) => {
|
|
280
|
+
if (record.slot !== "identity:session") return;
|
|
281
|
+
if (record.outcome === "applied" && record.event === "SessionRead") finish({ ok: true });
|
|
282
|
+
else if (record.outcome === "failed" || record.outcome === "cancelled") finish({
|
|
283
|
+
ok: false,
|
|
284
|
+
reason: record.error_code
|
|
285
|
+
});
|
|
286
|
+
});
|
|
287
|
+
if (done) {
|
|
288
|
+
unsubscribe();
|
|
289
|
+
return;
|
|
290
|
+
}
|
|
291
|
+
stop = unsubscribe;
|
|
292
|
+
timer = setTimeout(() => finish({
|
|
293
|
+
ok: false,
|
|
294
|
+
reason: "UNKNOWN"
|
|
295
|
+
}), SESSION_SETTLE_LIMIT_MS);
|
|
296
|
+
});
|
|
218
297
|
const read = async (invocation) => {
|
|
219
298
|
const result = await runtime.send({ _tag: "ReadSession" }, invocation);
|
|
220
|
-
|
|
299
|
+
const refused = failure(result);
|
|
300
|
+
if (refused === null) return { ok: true };
|
|
301
|
+
return refused.reason === "SUPERSEDED" ? settledSession(invocation) : refused;
|
|
221
302
|
};
|
|
222
303
|
const ensureAccount = async (invocation) => {
|
|
223
304
|
const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
|
|
224
305
|
return failure(result) ?? { ok: true };
|
|
225
306
|
};
|
|
307
|
+
const settledAccount = (invocation) => new Promise((resolve) => {
|
|
308
|
+
let done = false;
|
|
309
|
+
let stop = null;
|
|
310
|
+
const onAbort = () => finish({
|
|
311
|
+
ok: false,
|
|
312
|
+
reason: "CANCELLED"
|
|
313
|
+
});
|
|
314
|
+
const finish = (result) => {
|
|
315
|
+
if (done) return;
|
|
316
|
+
done = true;
|
|
317
|
+
stop?.();
|
|
318
|
+
invocation?.signal?.removeEventListener("abort", onAbort);
|
|
319
|
+
resolve(result);
|
|
320
|
+
};
|
|
321
|
+
if (invocation?.signal?.aborted) {
|
|
322
|
+
onAbort();
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
invocation?.signal?.addEventListener("abort", onAbort, { once: true });
|
|
326
|
+
const unsubscribe = runtime.subscribe((state) => {
|
|
327
|
+
if (!accountInFlight(state)) finish({ ok: true });
|
|
328
|
+
});
|
|
329
|
+
if (done) {
|
|
330
|
+
unsubscribe();
|
|
331
|
+
return;
|
|
332
|
+
}
|
|
333
|
+
stop = unsubscribe;
|
|
334
|
+
if (!accountInFlight(runtime.snapshot())) finish({ ok: true });
|
|
335
|
+
});
|
|
226
336
|
const reachClaimed = async (invocation) => {
|
|
227
337
|
let state = runtime.snapshot();
|
|
338
|
+
if (accountInFlight(state)) {
|
|
339
|
+
const settled = await settledAccount(invocation);
|
|
340
|
+
if (!settled.ok) return settled;
|
|
341
|
+
state = runtime.snapshot();
|
|
342
|
+
}
|
|
228
343
|
if (state.phase !== "authenticated" || state.account.at === "unknown") {
|
|
229
344
|
const result = await runtime.send({ _tag: "EnsureAccount" }, invocation);
|
|
230
345
|
const refused = failure(result);
|
|
@@ -236,6 +351,16 @@ function createAuth(client, clearAuthenticatedQueries) {
|
|
|
236
351
|
reason: "WRONG_STATE"
|
|
237
352
|
};
|
|
238
353
|
if (state.account.at === "claimed") return { ok: true };
|
|
354
|
+
if (accountInFlight(state)) {
|
|
355
|
+
const settled = await settledAccount(invocation);
|
|
356
|
+
if (!settled.ok) return settled;
|
|
357
|
+
state = runtime.snapshot();
|
|
358
|
+
if (state.phase !== "authenticated") return {
|
|
359
|
+
ok: false,
|
|
360
|
+
reason: "WRONG_STATE"
|
|
361
|
+
};
|
|
362
|
+
if (state.account.at === "claimed") return { ok: true };
|
|
363
|
+
}
|
|
239
364
|
const event = state.account.at === "failed" ? { _tag: "RetryAccount" } : state.account.at === "counterfactual" ? { _tag: "ClaimAccount" } : { _tag: "EnsureAccount" };
|
|
240
365
|
const result = await runtime.send(event, invocation);
|
|
241
366
|
const refused = failure(result);
|
|
@@ -256,13 +381,13 @@ function createAuth(client, clearAuthenticatedQueries) {
|
|
|
256
381
|
ok: false,
|
|
257
382
|
reason: "INVALID_INPUT"
|
|
258
383
|
};
|
|
384
|
+
const refreshed = await read(invocation);
|
|
385
|
+
if (!refreshed.ok) return refreshed;
|
|
259
386
|
const current = runtime.snapshot();
|
|
260
387
|
if (current.phase !== "authenticated" || !current.profileComplete) {
|
|
261
388
|
const completed = await runtime.completeProfile(submission.profileDetails, invocation);
|
|
262
389
|
if (!completed.ok) return completed;
|
|
263
390
|
}
|
|
264
|
-
const refreshed = await read(invocation);
|
|
265
|
-
if (!refreshed.ok) return refreshed;
|
|
266
391
|
const claimed = await reachClaimed(invocation);
|
|
267
392
|
return claimed.ok ? {
|
|
268
393
|
ok: true,
|
|
@@ -339,12 +464,13 @@ function createAuth(client, clearAuthenticatedQueries) {
|
|
|
339
464
|
}),
|
|
340
465
|
createOrganization: (submission, options) => guarded(runtime, "createOrganization", options, async (invocation) => {
|
|
341
466
|
const current = runtime.snapshot();
|
|
467
|
+
const running = runningOrganization(current);
|
|
468
|
+
if (running !== null) return {
|
|
469
|
+
ok: true,
|
|
470
|
+
orgId: running
|
|
471
|
+
};
|
|
342
472
|
if (current.phase === "authenticated" && current.account.at === "claimed") {
|
|
343
473
|
const org = current.account.org;
|
|
344
|
-
if (org !== null && (org.at === "loading" || org.at === "settingUp" || org.at === "ready")) return {
|
|
345
|
-
ok: true,
|
|
346
|
-
orgId: org.orgId
|
|
347
|
-
};
|
|
348
474
|
if (org?.at === "failed" && org.orgId !== null) {
|
|
349
475
|
if (!org.retryable) return {
|
|
350
476
|
ok: false,
|
|
@@ -359,6 +485,11 @@ function createAuth(client, clearAuthenticatedQueries) {
|
|
|
359
485
|
}
|
|
360
486
|
const prepared = await prepareOrganization(submission, invocation);
|
|
361
487
|
if (!prepared.ok) return prepared;
|
|
488
|
+
const opened = runningOrganization(runtime.snapshot());
|
|
489
|
+
if (opened !== null) return {
|
|
490
|
+
ok: true,
|
|
491
|
+
orgId: opened
|
|
492
|
+
};
|
|
362
493
|
const created = await runtime.send({
|
|
363
494
|
_tag: "CreateOrganization",
|
|
364
495
|
draft: prepared.organization
|
|
@@ -440,7 +571,7 @@ function CapxulIdentityProvider({ client, children }) {
|
|
|
440
571
|
}, []);
|
|
441
572
|
const value = useMemo(() => {
|
|
442
573
|
if (client === null || runtime === null) return null;
|
|
443
|
-
const send = (event, options) => runtime.send(event,
|
|
574
|
+
const send = (event, options) => runtime.send(event, toInvocationControls(options));
|
|
444
575
|
const clearAuthenticatedQueries = async () => {
|
|
445
576
|
await queryClient.cancelQueries({ queryKey: capxulKeys.root });
|
|
446
577
|
await queryClient.resetQueries({ queryKey: capxulKeys.root });
|
|
@@ -819,4 +950,4 @@ function organizationForm(props, state, auth, submitted) {
|
|
|
819
950
|
});
|
|
820
951
|
}
|
|
821
952
|
//#endregion
|
|
822
|
-
export { useCapxulAuth as a, useCapxulIdentityOrNull as c,
|
|
953
|
+
export { useCapxulAuth as a, useCapxulIdentityOrNull as c, toInvocationControls as d, toInvocationOptions as f, useCapxul as h, entered as i, useCapxulSend as l, useCapxulClientOrNull as m, CapxulOnboardingController as n, useCapxulDestination as o, capxulKeys as p, CapxulProvider as r, useCapxulIdentity as s, CapxulAuthenticationController as t, useCapxulTransitions as u };
|
package/dist/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { A as entered, C as CreateOrganizationFailure, D as OrganizationDetails, E as InvocationOptions, F as useCapxulTransitions, M as useCapxulDestination, N as useCapxulIdentity, O as ProfileDetails, P as useCapxulSend, S as CapxulSend, T as Destination, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulAuth, k as SendResult, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as CreateOrganizationSubmission, x as CapxulAuth, y as SignedOutState } from "./controllers-
|
|
1
|
+
import { A as entered, C as CreateOrganizationFailure, D as OrganizationDetails, E as InvocationOptions, F as useCapxulTransitions, M as useCapxulDestination, N as useCapxulIdentity, O as ProfileDetails, P as useCapxulSend, S as CapxulSend, T as Destination, _ as ReadyDestination, a as AuthenticationSlots, b as Slot, c as ControllerAction, d as OnboardingControllerProps, f as OrgFailure, g as ProfileSlotProps, h as PendingAuthState, i as AuthenticatedState, j as useCapxulAuth, k as SendResult, l as FaultedState, m as OtpPendingState, n as AccountProgress, o as CapxulAuthenticationController, p as OrgProgress, r as ActionResult, s as CapxulOnboardingController, t as AccountFailure, u as NavigationAction, v as RetryAction, w as CreateOrganizationSubmission, x as CapxulAuth, y as SignedOutState } from "./controllers-BWmKRFy6.mjs";
|
|
2
2
|
import { ReactNode, RefCallback } from "react";
|
|
3
3
|
import { QueryClient, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
|
|
4
4
|
import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, BudgetId, CapxulClient, CapxulError, CapxulResult, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, IdentityDestination, InviteMemberInput, MemberView, Money, MoneyParseErrorReason, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, PartyId, Payment, PaymentDirection, PaymentDocumentRef, PaymentDocumentRender, PaymentStatus, PaymentTiming, PaymentType, PaymentsPayInput, PayrollGroupId, PayrollGroupInput, PayrollRunId, PayrollRunStatus, Permission, PermissionMethods, PermissionReadResult, Profile, RoleView, SubmittedPermissionExecution, isClaimed, isRestoring } from "@capxul/sdk";
|
|
@@ -222,6 +222,7 @@ type ProfileDraft = {
|
|
|
222
222
|
readonly withdrawalAddress: string;
|
|
223
223
|
readonly handle?: string;
|
|
224
224
|
readonly payoutAddresses?: readonly PayoutDraftEntry[];
|
|
225
|
+
readonly imageStorageId?: string;
|
|
225
226
|
};
|
|
226
227
|
type OrganizationDraft = {
|
|
227
228
|
readonly name: string;
|
|
@@ -229,6 +230,7 @@ type OrganizationDraft = {
|
|
|
229
230
|
readonly country: string;
|
|
230
231
|
readonly bio?: string;
|
|
231
232
|
readonly size?: string;
|
|
233
|
+
readonly logoStorageId?: string;
|
|
232
234
|
};
|
|
233
235
|
type OnboardingOrigin = {
|
|
234
236
|
readonly kind: "personal";
|
|
@@ -251,6 +253,8 @@ type OnboardingJourney = {
|
|
|
251
253
|
readonly organization?: OrganizationDraft;
|
|
252
254
|
readonly stableHandle?: string;
|
|
253
255
|
readonly organizationId?: string;
|
|
256
|
+
/** #1955: what the organization submit sent, kept for resume. */
|
|
257
|
+
readonly submission?: CreateOrganizationSubmission;
|
|
254
258
|
};
|
|
255
259
|
/**
|
|
256
260
|
* The app-facing projection input: where a resumed journey stands. Consumers
|
|
@@ -335,6 +339,21 @@ type UseCapxulImageUploadReturn = UseMutationResult<{
|
|
|
335
339
|
*/
|
|
336
340
|
declare function useCapxulImageUpload(): UseCapxulImageUploadReturn;
|
|
337
341
|
//#endregion
|
|
342
|
+
//#region src/headless/media/use-capxul-upload-image.d.ts
|
|
343
|
+
type UseCapxulUploadImageReturn = UseMutationResult<{
|
|
344
|
+
readonly storageId: string;
|
|
345
|
+
}, CapxulError, Blob>;
|
|
346
|
+
/**
|
|
347
|
+
* #1955: upload only. Hands back the storage id for a CREATE call to carry
|
|
348
|
+
* (`ProfileDetails.imageStorageId`, `OrganizationDetails.logoStorageId`).
|
|
349
|
+
*
|
|
350
|
+
* `useCapxulImageUpload` is upload+bind and stays as it is for the settings
|
|
351
|
+
* pages. It cannot serve onboarding: the row it binds to does not exist yet.
|
|
352
|
+
* Nothing is bound here, so nothing is invalidated either — the create call
|
|
353
|
+
* that carries the id owns the cache change.
|
|
354
|
+
*/
|
|
355
|
+
declare function useCapxulUploadImage(): UseCapxulUploadImageReturn;
|
|
356
|
+
//#endregion
|
|
338
357
|
//#region src/headless/contacts/use-contacts.d.ts
|
|
339
358
|
type ContactsActor = {
|
|
340
359
|
readonly kind: "personal";
|
|
@@ -364,9 +383,9 @@ interface Contact {
|
|
|
364
383
|
interface ContactRow extends Contact {
|
|
365
384
|
/** Ours: one initials rule, not one copy per screen. */
|
|
366
385
|
readonly initials: string;
|
|
367
|
-
readonly rename: (name: string) => void;
|
|
368
|
-
readonly hide: () => void;
|
|
369
|
-
readonly unhide: () => void;
|
|
386
|
+
readonly rename: (name: string, options?: InvocationOptions) => void;
|
|
387
|
+
readonly hide: (options?: InvocationOptions) => void;
|
|
388
|
+
readonly unhide: (options?: InvocationOptions) => void;
|
|
370
389
|
}
|
|
371
390
|
/** ADR-0023 R1: refusal CODES, never sentences — the app owns the words. */
|
|
372
391
|
type ContactsRefusal = "loading" | "org-unavailable" | "unavailable";
|
|
@@ -402,7 +421,13 @@ interface ContactsListOptions {
|
|
|
402
421
|
interface ContactsAddSlice {
|
|
403
422
|
readonly value: string;
|
|
404
423
|
readonly change: (text: string) => void;
|
|
405
|
-
|
|
424
|
+
/**
|
|
425
|
+
* #1960 R02: hand it the options the screen captured BEFORE the click. The
|
|
426
|
+
* same snapshot reaches the SDK add call and comes back on `onAdded`/
|
|
427
|
+
* `onFailed`, so the UI observation and the operation share one identity even
|
|
428
|
+
* when the reply lands after an account switch. Omitted stays omitted.
|
|
429
|
+
*/
|
|
430
|
+
readonly submit: (options?: InvocationOptions) => void;
|
|
406
431
|
readonly isSubmitting: boolean;
|
|
407
432
|
readonly blocked: boolean;
|
|
408
433
|
readonly blockedReason: ContactsAddBlockedReason | null;
|
|
@@ -412,9 +437,14 @@ interface ContactsAddSlice {
|
|
|
412
437
|
//#region src/headless/contacts/contacts.d.ts
|
|
413
438
|
interface CapxulContactsProps {
|
|
414
439
|
readonly actor: ContactsActor;
|
|
415
|
-
|
|
440
|
+
/**
|
|
441
|
+
* `options` is exactly what the caller handed `.Add.submit` or a row verb, so
|
|
442
|
+
* the screen's own observation of the finished action can reuse the attempt
|
|
443
|
+
* identity the SDK operation ran under (#1960 R02).
|
|
444
|
+
*/
|
|
445
|
+
readonly onAdded: (contact: Contact, options?: InvocationOptions) => void;
|
|
416
446
|
/** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
|
|
417
|
-
readonly onFailed: (error: CapxulError) => void;
|
|
447
|
+
readonly onFailed: (error: CapxulError, options?: InvocationOptions) => void;
|
|
418
448
|
readonly children: ReactNode;
|
|
419
449
|
}
|
|
420
450
|
declare function Root$6({ actor, onAdded, onFailed, children }: CapxulContactsProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -526,7 +556,12 @@ interface ActivityRowsSlice {
|
|
|
526
556
|
readonly rows: readonly ActivityRow[];
|
|
527
557
|
readonly isLoading: boolean;
|
|
528
558
|
readonly error: CapxulError | null;
|
|
529
|
-
|
|
559
|
+
/**
|
|
560
|
+
* #1960 R02: pass the options captured before the retry was selected and the
|
|
561
|
+
* re-read runs under the same attempt identity as the UI observation. Omit
|
|
562
|
+
* them and the read keeps its own invocation context.
|
|
563
|
+
*/
|
|
564
|
+
readonly retry: (options?: InvocationOptions) => void;
|
|
530
565
|
/** Server read time of the newest page, so the app can say which read is older. */
|
|
531
566
|
readonly observedAt: number | null;
|
|
532
567
|
}
|
|
@@ -570,7 +605,8 @@ interface CsvExport {
|
|
|
570
605
|
readonly truncated: boolean;
|
|
571
606
|
}
|
|
572
607
|
interface ActivityExportSlice {
|
|
573
|
-
|
|
608
|
+
/** Same contract as `retry`: the export's pages run under the caller's attempt. */
|
|
609
|
+
readonly toCsv: (options?: InvocationOptions) => Promise<CsvExport>;
|
|
574
610
|
readonly isExporting: boolean;
|
|
575
611
|
}
|
|
576
612
|
//#endregion
|
|
@@ -1032,4 +1068,4 @@ declare const capxulKeys: {
|
|
|
1032
1068
|
payment: (paymentId: string | undefined) => readonly ["capxul", "payments", string];
|
|
1033
1069
|
};
|
|
1034
1070
|
//#endregion
|
|
1035
|
-
export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationFailure, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type HandleAvailability, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulHandleAvailabilityReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
|
|
1071
|
+
export { type AccountFailure, type AccountProgress, type ActionResult, type ActivityDetailSlice, type ActivityExportSlice, type ActivityFilterValues, type ActivityFiltersSlice, type ActivityLoadMoreSlice, type ActivityReceipt, type ActivityRow, type ActivityRowsSlice, type ActivitySearchSlice, type ActivitySummarySlice, type AuthenticatedState, type AuthenticationSlots, type CanReason, CapxulActivity, type CapxulActivityProps, type CapxulAuth, CapxulAuthenticationController, type CapxulBootstrapState, type CapxulBootstrapStatus, CapxulContacts, type CapxulContactsProps, CapxulDashboardAccess, type CapxulDashboardAccessProps, CapxulOnboardingController, CapxulOrgMember, type CapxulOrgMemberProps, CapxulPayroll, type CapxulPayrollProps, CapxulPayrollRun, type CapxulPayrollRunBlockedReason, type CapxulPayrollRunProps, CapxulProvider, type CapxulProviderProps, type CapxulSend, CapxulSendMoney, type CapxulSendMoneyBlockedReason, type CapxulSendMoneyProps, type Contact, type ContactRelationship, type ContactRow, type ContactsActor, type ContactsAddBlockedReason, type ContactsAddError, type ContactsAddSlice, type ContactsListOptions, type ContactsListSlice, type ContactsRefusal, type ContactsSummarySlice, type ControllerAction, type CreateOrganizationFailure, type CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, type HandleAvailability, type ImageUploadInput, type ImageUploadTarget, type InvocationOptions, type NavigationAction, type OnboardingControllerProps, type OnboardingIntent, type OnboardingJourney, type OnboardingJourneyPosition, type OnboardingOrigin, type OnboardingStep, type OrgFailure, type OrgMemberAction, type OrgMemberCanSlice, type OrgMemberStanding, type OrgMemberStandingSlice, type OrgProgress, type OrganizationDetails, type OrganizationDraft, type OtpPendingState, type PayoutDraftChain, type PayoutDraftEntry, type PayrollGroupRow, type PayrollGroupsSlice, type PayrollRecipientOption, type PayrollRunActionsSlice, type PayrollRunAmountEntry, type PayrollRunAmountsSlice, type PayrollRunAssetSlice, type PayrollRunGroupOption, type PayrollRunPrefill, type PayrollRunRecipientsSlice, type PayrollRunStatus, type PayrollRunSummarySlice, type PayrollSummarySlice, type PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendMoneySourceError, type SendMoneySourceOption, type SendMoneySourceSlice, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, type UseCapxulHandleAvailabilityReturn, type UseCapxulImageUploadReturn, type UseCapxulInviteMemberReturn, type UseCapxulOrgMembersOptions, type UseCapxulOrgMembersReturn, type UseCapxulOrgRolesOptions, type UseCapxulOrgRolesReturn, type UseCapxulOrgTreasuryOptions, type UseCapxulOrgTreasuryReturn, type UseCapxulOrgsReturn, type UseCapxulPayReturn, type UseCapxulPaymentReturn, type UseCapxulPaymentsReturn, type UseCapxulProfileReturn, type UseCapxulRedirectPaymentReturn, type UseCapxulUploadImageReturn, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUploadImage };
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
"use client";
|
|
2
|
-
import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as
|
|
2
|
+
import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as toInvocationControls, f as toInvocationOptions, h as useCapxul, i as entered, l as useCapxulSend, m as useCapxulClientOrNull, n as CapxulOnboardingController, o as useCapxulDestination, p as capxulKeys, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-DaT-AGx6.mjs";
|
|
3
3
|
import { createContext, useCallback, useContext, useEffect, useMemo, useRef, useState, useSyncExternalStore } from "react";
|
|
4
4
|
import { useInfiniteQuery, useMutation, useQuery, useQueryClient } from "@tanstack/react-query";
|
|
5
5
|
import { CAPXUL_OPERATIONS, CapxulError, EVM_ADDRESS_RE, Errors, HANDLE_RE, PAYMENT_DIRECTIONS, PAYMENT_STATUSES, fingerprintPaymentIntent, formatMoney, isCapxulError, isClaimed, isClaimed as isClaimed$1, isMoneyParseError, isRestoring, isRestoring as isRestoring$1, parseMoney, paymentPhase, resolveIdentityDestination, toEvmAddress, toPartyId } from "@capxul/sdk";
|
|
@@ -702,7 +702,8 @@ function isValidJourney(value) {
|
|
|
702
702
|
"profile",
|
|
703
703
|
"organization",
|
|
704
704
|
"stableHandle",
|
|
705
|
-
"organizationId"
|
|
705
|
+
"organizationId",
|
|
706
|
+
"submission"
|
|
706
707
|
])) return false;
|
|
707
708
|
if (!isBoundedId(value.ownerId)) return false;
|
|
708
709
|
if (!isBoundedId(value.journeyId) || !value.journeyId.startsWith("journey_")) return false;
|
|
@@ -712,6 +713,7 @@ function isValidJourney(value) {
|
|
|
712
713
|
if (value.origin !== void 0 && !isOrigin(value.origin)) return false;
|
|
713
714
|
if (value.profile !== void 0 && !isProfileDraft(value.profile)) return false;
|
|
714
715
|
if (value.organization !== void 0 && !isOrganizationDraft(value.organization)) return false;
|
|
716
|
+
if (value.submission !== void 0 && !isCreateOrganizationSubmission(value.submission)) return false;
|
|
715
717
|
if (value.stableHandle !== void 0 && !isDraftText(value.stableHandle)) return false;
|
|
716
718
|
if (value.organizationId !== void 0 && !isBoundedId(value.organizationId)) return false;
|
|
717
719
|
if (value.organization !== void 0 && value.stableHandle !== value.organization.handle) return false;
|
|
@@ -734,12 +736,33 @@ function isProfileDraft(value) {
|
|
|
734
736
|
"country",
|
|
735
737
|
"withdrawalAddress",
|
|
736
738
|
"handle",
|
|
737
|
-
"payoutAddresses"
|
|
739
|
+
"payoutAddresses",
|
|
740
|
+
"imageStorageId"
|
|
738
741
|
]) || !isDraftText(value.displayName) || !isDraftText(value.country) || !isDraftText(value.withdrawalAddress)) return false;
|
|
739
742
|
if (value.handle !== void 0 && !isDraftText(value.handle)) return false;
|
|
740
743
|
if (value.payoutAddresses !== void 0 && !isPayoutDraftList(value.payoutAddresses)) return false;
|
|
744
|
+
if (value.imageStorageId !== void 0 && !isBoundedId(value.imageStorageId)) return false;
|
|
741
745
|
return true;
|
|
742
746
|
}
|
|
747
|
+
/**
|
|
748
|
+
* The submitted organization (#1955). ONE validator now — the app's duplicate
|
|
749
|
+
* of it is deleted, so a submit cannot be written by two writers with
|
|
750
|
+
* disagreeing rules and then rejected here.
|
|
751
|
+
*/
|
|
752
|
+
function isCreateOrganizationSubmission(value) {
|
|
753
|
+
if (!isRecord(value) || !hasOnlyKeys(value, ["profileDetails", "organization"])) return false;
|
|
754
|
+
const { profileDetails, organization } = value;
|
|
755
|
+
if (!isRecord(profileDetails) || !hasOnlyKeys(profileDetails, [
|
|
756
|
+
"displayName",
|
|
757
|
+
"country",
|
|
758
|
+
"handle",
|
|
759
|
+
"imageStorageId",
|
|
760
|
+
"payoutAddresses"
|
|
761
|
+
]) || !isDraftText(profileDetails.displayName) || !isDraftText(profileDetails.country) || !isDraftText(profileDetails.handle)) return false;
|
|
762
|
+
if (profileDetails.imageStorageId !== void 0 && !isBoundedId(profileDetails.imageStorageId)) return false;
|
|
763
|
+
if (profileDetails.payoutAddresses !== void 0 && !isPayoutDraftList(profileDetails.payoutAddresses)) return false;
|
|
764
|
+
return isOrganizationDraft(organization);
|
|
765
|
+
}
|
|
743
766
|
function isPayoutDraftList(value) {
|
|
744
767
|
return Array.isArray(value) && value.length <= MAX_PAYOUT_DRAFT_ENTRIES && value.every((entry) => isRecord(entry) && hasOnlyKeys(entry, ["chain", "address"]) && (entry.chain === "evm" || entry.chain === "solana" || entry.chain === "starknet") && isDraftText(entry.address));
|
|
745
768
|
}
|
|
@@ -749,10 +772,12 @@ function isOrganizationDraft(value) {
|
|
|
749
772
|
"handle",
|
|
750
773
|
"country",
|
|
751
774
|
"bio",
|
|
752
|
-
"size"
|
|
775
|
+
"size",
|
|
776
|
+
"logoStorageId"
|
|
753
777
|
]) || !isDraftText(value.name) || !isDraftText(value.handle) || !isDraftText(value.country)) return false;
|
|
754
778
|
if (value.bio !== void 0 && !isDraftText(value.bio)) return false;
|
|
755
779
|
if (value.size !== void 0 && !isDraftText(value.size)) return false;
|
|
780
|
+
if (value.logoStorageId !== void 0 && !isBoundedId(value.logoStorageId)) return false;
|
|
756
781
|
return true;
|
|
757
782
|
}
|
|
758
783
|
function isDraftText(value) {
|
|
@@ -836,7 +861,26 @@ function useCapxulImageUpload() {
|
|
|
836
861
|
});
|
|
837
862
|
}
|
|
838
863
|
//#endregion
|
|
864
|
+
//#region src/headless/media/use-capxul-upload-image.ts
|
|
865
|
+
/**
|
|
866
|
+
* #1955: upload only. Hands back the storage id for a CREATE call to carry
|
|
867
|
+
* (`ProfileDetails.imageStorageId`, `OrganizationDetails.logoStorageId`).
|
|
868
|
+
*
|
|
869
|
+
* `useCapxulImageUpload` is upload+bind and stays as it is for the settings
|
|
870
|
+
* pages. It cannot serve onboarding: the row it binds to does not exist yet.
|
|
871
|
+
* Nothing is bound here, so nothing is invalidated either — the create call
|
|
872
|
+
* that carries the id owns the cache change.
|
|
873
|
+
*/
|
|
874
|
+
function useCapxulUploadImage() {
|
|
875
|
+
const client = useCapxulClientOrNull();
|
|
876
|
+
return useMutation({ mutationFn: async (blob) => {
|
|
877
|
+
return { storageId: unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.media.uploadImage).media.uploadImage(blob)).storageId };
|
|
878
|
+
} });
|
|
879
|
+
}
|
|
880
|
+
//#endregion
|
|
839
881
|
//#region src/headless/contacts/use-contacts.ts
|
|
882
|
+
/** One captured snapshot, or nothing — never a fabricated empty options object. */
|
|
883
|
+
const carry = (options) => options === void 0 ? {} : { options };
|
|
840
884
|
function useContacts(input) {
|
|
841
885
|
const { actor, onAdded, onFailed } = input;
|
|
842
886
|
const client = useCapxulClientOrNull();
|
|
@@ -853,35 +897,40 @@ function useContacts(input) {
|
|
|
853
897
|
const writeMutate = useMutation({
|
|
854
898
|
mutationFn: async (command) => {
|
|
855
899
|
const target = requireBook(book, `addressBook.${command.kind}`);
|
|
900
|
+
const controls = toInvocationControls(command.options);
|
|
856
901
|
return unwrapCapxulResult(command.kind === "rename" ? await target.label({
|
|
857
902
|
entryId: command.id,
|
|
858
903
|
label: command.name
|
|
859
|
-
}) : command.kind === "hide" ? await target.hide(command.id) : await target.unhide(command.id));
|
|
904
|
+
}, controls) : command.kind === "hide" ? await target.hide(command.id, controls) : await target.unhide(command.id, controls));
|
|
860
905
|
},
|
|
861
906
|
onSettled: invalidate,
|
|
862
|
-
onError: onFailed
|
|
907
|
+
onError: (error, command) => onFailed(error, command.options)
|
|
863
908
|
}).mutate;
|
|
864
909
|
const [value, setValue] = useState("");
|
|
865
910
|
const [addError, setAddError] = useState(null);
|
|
866
911
|
const addContact = useMutation({
|
|
867
|
-
mutationFn: async (
|
|
912
|
+
mutationFn: async (command) => unwrapCapxulResult(await requireBook(book, CAPXUL_OPERATIONS.addressBook.add).add({ ref: command.ref }, toInvocationControls(command.options))),
|
|
868
913
|
onSettled: invalidate
|
|
869
914
|
});
|
|
870
915
|
const addMutate = addContact.mutate;
|
|
871
916
|
const blockedReason = refusal !== null ? "org-unavailable" : value.trim() === "" ? "empty" : null;
|
|
872
917
|
const submitGate = useRef(false);
|
|
873
|
-
const submit = useCallback(() => {
|
|
918
|
+
const submit = useCallback((options) => {
|
|
874
919
|
if (blockedReason !== null || submitGate.current) return;
|
|
920
|
+
const attempt = toInvocationOptions(options);
|
|
875
921
|
submitGate.current = true;
|
|
876
922
|
setAddError(null);
|
|
877
|
-
addMutate(
|
|
923
|
+
addMutate({
|
|
924
|
+
ref: refFromTypedText(value),
|
|
925
|
+
...carry(attempt)
|
|
926
|
+
}, {
|
|
878
927
|
onSuccess: (entry) => {
|
|
879
928
|
setValue("");
|
|
880
|
-
onAdded(toContact(entry));
|
|
929
|
+
onAdded(toContact(entry), attempt);
|
|
881
930
|
},
|
|
882
931
|
onError: (error) => {
|
|
883
932
|
setAddError(error.code === "INVALID_INPUT" ? "unresolved" : "failed");
|
|
884
|
-
onFailed(error);
|
|
933
|
+
onFailed(error, attempt);
|
|
885
934
|
},
|
|
886
935
|
onSettled: () => {
|
|
887
936
|
submitGate.current = false;
|
|
@@ -902,18 +951,21 @@ function useContacts(input) {
|
|
|
902
951
|
book,
|
|
903
952
|
scope,
|
|
904
953
|
refusal,
|
|
905
|
-
rename: useCallback((id, name) => writeMutate({
|
|
954
|
+
rename: useCallback((id, name, options) => writeMutate({
|
|
906
955
|
kind: "rename",
|
|
907
956
|
id,
|
|
908
|
-
name
|
|
957
|
+
name,
|
|
958
|
+
...carry(toInvocationOptions(options))
|
|
909
959
|
}), [writeMutate]),
|
|
910
|
-
hide: useCallback((id) => writeMutate({
|
|
960
|
+
hide: useCallback((id, options) => writeMutate({
|
|
911
961
|
kind: "hide",
|
|
912
|
-
id
|
|
962
|
+
id,
|
|
963
|
+
...carry(toInvocationOptions(options))
|
|
913
964
|
}), [writeMutate]),
|
|
914
|
-
unhide: useCallback((id) => writeMutate({
|
|
965
|
+
unhide: useCallback((id, options) => writeMutate({
|
|
915
966
|
kind: "unhide",
|
|
916
|
-
id
|
|
967
|
+
id,
|
|
968
|
+
...carry(toInvocationOptions(options))
|
|
917
969
|
}), [writeMutate]),
|
|
918
970
|
add: {
|
|
919
971
|
value,
|
|
@@ -947,9 +999,9 @@ function useContactsList(engine, options) {
|
|
|
947
999
|
if (entries === void 0) return [];
|
|
948
1000
|
return (limit === void 0 ? entries : entries.slice(0, limit)).map((entry) => Object.assign(toContact(entry), {
|
|
949
1001
|
initials: initialsOf(entry.label),
|
|
950
|
-
rename: (name) => rename(entry.id, name),
|
|
951
|
-
hide: () => hide(entry.id),
|
|
952
|
-
unhide: () => unhide(entry.id)
|
|
1002
|
+
rename: (name, attempt) => rename(entry.id, name, attempt),
|
|
1003
|
+
hide: (attempt) => hide(entry.id, attempt),
|
|
1004
|
+
unhide: (attempt) => unhide(entry.id, attempt)
|
|
953
1005
|
}));
|
|
954
1006
|
}, [
|
|
955
1007
|
entries,
|
|
@@ -1525,6 +1577,12 @@ function useActivity(input) {
|
|
|
1525
1577
|
if (filter !== void 0) params.filter = filter;
|
|
1526
1578
|
return params;
|
|
1527
1579
|
}, [actor, filter]);
|
|
1580
|
+
const selectedRetry = useRef(void 0);
|
|
1581
|
+
const takeSelectedRetry = useCallback(() => {
|
|
1582
|
+
const attempt = selectedRetry.current;
|
|
1583
|
+
selectedRetry.current = void 0;
|
|
1584
|
+
return toInvocationControls(attempt);
|
|
1585
|
+
}, []);
|
|
1528
1586
|
const query = useInfiniteQuery({
|
|
1529
1587
|
queryKey: [
|
|
1530
1588
|
...capxulKeys.activity,
|
|
@@ -1534,7 +1592,7 @@ function useActivity(input) {
|
|
|
1534
1592
|
filter ?? "none"
|
|
1535
1593
|
],
|
|
1536
1594
|
queryFn: async ({ pageParam }) => {
|
|
1537
|
-
return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit)));
|
|
1595
|
+
return unwrapCapxulResult(await requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list).activity.list(listParams(pageParam, limit), takeSelectedRetry()));
|
|
1538
1596
|
},
|
|
1539
1597
|
initialPageParam: void 0,
|
|
1540
1598
|
getNextPageParam: (last) => last.cursor ?? void 0,
|
|
@@ -1582,14 +1640,15 @@ function useActivity(input) {
|
|
|
1582
1640
|
observerRef.current = observer;
|
|
1583
1641
|
}, [loadMore]);
|
|
1584
1642
|
const [isExporting, setIsExporting] = useState(false);
|
|
1585
|
-
const toCsv = useCallback(async () => {
|
|
1643
|
+
const toCsv = useCallback(async (options) => {
|
|
1586
1644
|
setIsExporting(true);
|
|
1645
|
+
const controls = toInvocationControls(toInvocationOptions(options));
|
|
1587
1646
|
try {
|
|
1588
1647
|
const bootstrapped = requireBootstrappedClient(client, CAPXUL_OPERATIONS.activity.list);
|
|
1589
1648
|
const items = [];
|
|
1590
1649
|
let cursor;
|
|
1591
1650
|
for (let page = 0; page < EXPORT_PAGE_CEILING; page += 1) {
|
|
1592
|
-
const result = unwrapCapxulResult(await bootstrapped.activity.list(listParams(cursor, EXPORT_PAGE_SIZE)));
|
|
1651
|
+
const result = unwrapCapxulResult(await bootstrapped.activity.list(listParams(cursor, EXPORT_PAGE_SIZE), controls));
|
|
1593
1652
|
items.push(...result.items);
|
|
1594
1653
|
cursor = result.cursor ?? void 0;
|
|
1595
1654
|
if (cursor === void 0) break;
|
|
@@ -1612,7 +1671,8 @@ function useActivity(input) {
|
|
|
1612
1671
|
setDirection(void 0);
|
|
1613
1672
|
setStatus([]);
|
|
1614
1673
|
}, []);
|
|
1615
|
-
const retry = useCallback(() => {
|
|
1674
|
+
const retry = useCallback((options) => {
|
|
1675
|
+
selectedRetry.current = toInvocationOptions(options);
|
|
1616
1676
|
refetch();
|
|
1617
1677
|
}, [refetch]);
|
|
1618
1678
|
return {
|
|
@@ -2763,7 +2823,9 @@ async function executeRunDraft(candidate, work) {
|
|
|
2763
2823
|
localStorage.setItem(storageKey(draft.scope), JSON.stringify(next));
|
|
2764
2824
|
draft = next;
|
|
2765
2825
|
}, clear);
|
|
2766
|
-
|
|
2826
|
+
try {
|
|
2827
|
+
clear();
|
|
2828
|
+
} catch {}
|
|
2767
2829
|
return run;
|
|
2768
2830
|
});
|
|
2769
2831
|
} catch (cause) {
|
|
@@ -3297,4 +3359,4 @@ const CapxulPayrollRun = Object.assign(Root, {
|
|
|
3297
3359
|
Actions
|
|
3298
3360
|
});
|
|
3299
3361
|
//#endregion
|
|
3300
|
-
export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions };
|
|
3362
|
+
export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, CapxulPayroll, CapxulPayrollRun, CapxulProvider, CapxulSendMoney, acknowledgeOnboardingDestination, activeOnboardingRecovery, capxulKeys, clearOnboardingJourney, currentOnboardingJourneyId, entered, invalidateOnboardingJourneyObservation, isClaimed, isRestoring, loadOnboardingJourney, onboardingJourneyPosition, saveOnboardingJourney, startOnboardingJourney, useCapxul, useCapxulAccountBalance, useCapxulAccountFund, useCapxulActivity, useCapxulActivityDetail, useCapxulAnnotateMovement, useCapxulAuth, useCapxulCancelPayment, useCapxulClaimPayment, useCapxulClientOrNull, useCapxulCreateCommitment, useCapxulCreateOrg, useCapxulDestination, useCapxulHandleAvailability, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUploadImage };
|
package/dist/testing/index.d.mts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-
|
|
1
|
+
import { a as AuthenticationSlots, d as OnboardingControllerProps } from "../controllers-BWmKRFy6.mjs";
|
|
2
2
|
import * as React from "react";
|
|
3
3
|
import { ReactNode } from "react";
|
|
4
4
|
import { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, SeedTestIdentityInput, createCapxulTestClient } from "@capxul/sdk/testing";
|
package/dist/testing/index.mjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-
|
|
1
|
+
import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DaT-AGx6.mjs";
|
|
2
2
|
import "react";
|
|
3
3
|
import { jsx } from "react/jsx-runtime";
|
|
4
4
|
import { createCapxulTestClient } from "@capxul/sdk/testing";
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@capxul/sdk-react",
|
|
3
|
-
"version": "4.
|
|
3
|
+
"version": "4.2.0-rc.10",
|
|
4
4
|
"repository": {
|
|
5
5
|
"type": "git",
|
|
6
6
|
"url": "git+https://github.com/Xelmar-tech/infrastructure.git",
|
|
@@ -26,7 +26,7 @@
|
|
|
26
26
|
"access": "public"
|
|
27
27
|
},
|
|
28
28
|
"dependencies": {
|
|
29
|
-
"@capxul/sdk": "4.
|
|
29
|
+
"@capxul/sdk": "4.2.0-rc.10"
|
|
30
30
|
},
|
|
31
31
|
"devDependencies": {
|
|
32
32
|
"@tanstack/react-query": "^5.66.9",
|
|
@@ -44,8 +44,8 @@
|
|
|
44
44
|
"vite-plus": "0.3.0",
|
|
45
45
|
"vitest": "4.1.11",
|
|
46
46
|
"@capxul/errors": "0.3.0",
|
|
47
|
-
"@capxul/
|
|
48
|
-
"@capxul/
|
|
47
|
+
"@capxul/typescript-config": "0.0.0",
|
|
48
|
+
"@capxul/types": "0.3.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
51
|
"@tanstack/react-query": "^5.66.9",
|