@capxul/sdk-react 2.4.0 → 2.5.1

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 CHANGED
@@ -61,6 +61,14 @@ export function Providers({ children }: { children: React.ReactNode }) {
61
61
  actor paths ship: a personal actor reads the account book, and an
62
62
  organization actor reads the organization book. The `managePeople` capability
63
63
  gate stays in the app, on `CapxulOrgMember.Can`.
64
+ - `CapxulPayroll` and `CapxulPayrollRun` are the two payroll compound
65
+ components. `CapxulPayroll` owns the payroll page's reads through its
66
+ `.Summary` and `.Groups` region parts; `CapxulPayrollRun` owns the run
67
+ composer through `.Recipients`, `.Amounts`, `.Asset`, `.Summary`, and
68
+ `.Actions`. A screen places any subset — the pay-now sheet places all five
69
+ run parts, the group sheet places two. `.Actions.blockedReason` names the
70
+ first false fact as a `CapxulPayrollRunBlockedReason` code, never a
71
+ sentence. Both engine hooks stay module-scoped.
64
72
 
65
73
  The packed npm package exposes `@capxul/sdk-react` and
66
74
  `@capxul/sdk-react/testing`. The workspace-only `@capxul/sdk-react/headless`
@@ -103,6 +103,20 @@ const capxulKeys = {
103
103
  scope,
104
104
  includeHidden ? "all" : "visible"
105
105
  ],
106
+ payrollRuns: (orgId) => [
107
+ "capxul",
108
+ "org",
109
+ orgId ?? "pending",
110
+ "payroll",
111
+ "runs"
112
+ ],
113
+ payrollGroups: (orgId) => [
114
+ "capxul",
115
+ "org",
116
+ orgId ?? "pending",
117
+ "payroll",
118
+ "groups"
119
+ ],
106
120
  activity: ["capxul", "activity"],
107
121
  activityDetail: (reference, actor = void 0) => [
108
122
  "capxul",
@@ -502,7 +516,7 @@ function clearClientScopedQueries(queryClient, ownsQueryClient) {
502
516
  queryClient.removeQueries({ predicate: (query) => isCapxulQueryKey(query.queryKey) });
503
517
  }
504
518
  function CapxulProvider(props) {
505
- const { publishableKey, client: injectedClient, requirement, signer, observability, queryClient, children } = props;
519
+ const { publishableKey, client: injectedClient, requirement, signer, observability, bootstrapBaseUrl, queryClient, children } = props;
506
520
  const [resolvedQueryClient] = useState(() => queryClient ?? makeDefaultQueryClient());
507
521
  const [ownsQueryClient] = useState(() => queryClient === void 0);
508
522
  const [attempt, setAttempt] = useState(0);
@@ -513,12 +527,14 @@ function CapxulProvider(props) {
513
527
  publishableKey,
514
528
  ...requirement === void 0 ? {} : { requirement },
515
529
  ...signer === void 0 ? {} : { signer },
516
- ...observability === void 0 ? {} : { observability }
530
+ ...observability === void 0 ? {} : { observability },
531
+ ...bootstrapBaseUrl === void 0 ? {} : { bootstrapBaseUrl }
517
532
  }, [
518
533
  publishableKey,
519
534
  requirement,
520
535
  signer,
521
536
  observability,
537
+ bootstrapBaseUrl,
522
538
  attempt
523
539
  ]);
524
540
  const [ownedBootstrap, setOwnedBootstrap] = useState(null);
package/dist/index.d.mts CHANGED
@@ -1,7 +1,7 @@
1
1
  import { A as useCapxulAuth, C as CreateOrganizationSubmission, D as ProfileDetails, E as OrganizationDetails, M as useCapxulIdentity, N as useCapxulSend, O as SendResult, P as useCapxulTransitions, S as CapxulSend, T as InvocationOptions, _ 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 useCapxulDestination, k as entered, 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 Destination, x as CapxulAuth, y as SignedOutState } from "./controllers-BT4YzBr9.mjs";
2
2
  import { ReactNode, RefCallback } from "react";
3
3
  import { QueryClient, UseMutationResult, UseQueryResult } from "@tanstack/react-query";
4
- import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, CapxulClient, CapxulError, CapxulSigner, CreateOrgInput, CurrentHoldings, HostObservability, IdentityDestination, InviteMemberInput, MemberView, Money, MoneyParseErrorReason, OrgId, OrgView, OrganizationPaymentBatchInput, OrganizationPaymentInput, PartyId, Payment, PaymentDirection, PaymentDocumentRef, PaymentDocumentRender, PaymentStatus, PaymentTiming, PaymentType, PaymentsPayInput, Permission, PermissionReadResult, Profile, RoleView, isClaimed, isRestoring } from "@capxul/sdk";
4
+ import { Account, AccountRequirement, ActivityAnnotation, ActivityAnnotationInput, ActivityDetail, ActivityKind, ActivityListParams, ActivityPage, ActivityPhase, ActivityRange, ActivityReference, ActorReference, AddressBookEntry, 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, PermissionReadResult, Profile, RoleView, isClaimed, isRestoring } from "@capxul/sdk";
5
5
 
6
6
  //#region src/provider.d.ts
7
7
  type CapxulProviderSharedProps = {
@@ -19,6 +19,13 @@ type CapxulProviderPublishableKeyProps = CapxulProviderSharedProps & {
19
19
  * with `requirement: "deployed"` — the SDK wires Openfort from bootstrap.
20
20
  */
21
21
  readonly signer?: CapxulSigner;
22
+ /**
23
+ * Where the bootstrap call goes. Default: the page's own origin, which a
24
+ * host app proxies to Capxul. Set it to the Capxul Site URL to call the
25
+ * backend directly and skip the host's proxy hop; the backend answers the
26
+ * route cross-origin for the publishable key's allowed origins.
27
+ */
28
+ readonly bootstrapBaseUrl?: string;
22
29
  };
23
30
  /**
24
31
  * Node / server / test path — a pre-built client is supplied; lifecycle stays
@@ -30,6 +37,7 @@ type CapxulProviderInjectedClientProps = CapxulProviderSharedProps & {
30
37
  readonly observability?: never;
31
38
  readonly requirement?: never;
32
39
  readonly signer?: never;
40
+ readonly bootstrapBaseUrl?: never;
33
41
  };
34
42
  type CapxulProviderProps = CapxulProviderPublishableKeyProps | CapxulProviderInjectedClientProps;
35
43
  declare function CapxulProvider(props: CapxulProviderProps): import("react/jsx-runtime").JSX.Element;
@@ -113,9 +121,32 @@ type PermissionId = Brand<string, "PermissionId">;
113
121
  type PermissionAssignmentId = Brand<string, "PermissionAssignmentId">;
114
122
  type PaymentCommandId = Brand<string, "PaymentCommandId">;
115
123
  type OrgId$1 = Brand<string, "OrgId">;
124
+ type CurrencyCode = Brand<SupportedCurrencyCode, "CurrencyCode">;
116
125
  type WeiAmount = Brand<string, "WeiAmount">;
117
126
  type RoleKey = Brand<string, "RoleKey">;
118
127
  type AllowanceKey = Brand<string, "AllowanceKey">;
128
+ declare const SUPPORTED_CURRENCIES: readonly [{
129
+ readonly code: "USD";
130
+ readonly symbol: "$";
131
+ readonly name: "US Dollar";
132
+ }, {
133
+ readonly code: "NGN";
134
+ readonly symbol: "NGN";
135
+ readonly name: "Nigerian Naira";
136
+ }, {
137
+ readonly code: "GHS";
138
+ readonly symbol: "GHS";
139
+ readonly name: "Ghanaian Cedi";
140
+ }, {
141
+ readonly code: "KES";
142
+ readonly symbol: "KSh";
143
+ readonly name: "Kenyan Shilling";
144
+ }, {
145
+ readonly code: "UGX";
146
+ readonly symbol: "USh";
147
+ readonly name: "Ugandan Shilling";
148
+ }];
149
+ type SupportedCurrencyCode = (typeof SUPPORTED_CURRENCIES)[number]["code"];
119
150
  //#endregion
120
151
  //#region src/hooks/use-capxul-permissions.d.ts
121
152
  declare const useCapxulPermissionCreate: (orgId: OrgId) => UseMutationResult<{
@@ -604,13 +635,13 @@ interface CapxulContactsProps {
604
635
  readonly onFailed: (error: CapxulError) => void;
605
636
  readonly children: ReactNode;
606
637
  }
607
- declare function Root$4({
638
+ declare function Root$6({
608
639
  actor,
609
640
  onAdded,
610
641
  onFailed,
611
642
  children
612
643
  }: CapxulContactsProps): import("react/jsx-runtime").JSX.Element;
613
- declare function Summary$1({
644
+ declare function Summary$3({
614
645
  children
615
646
  }: {
616
647
  readonly children: (slice: ContactsSummarySlice) => ReactNode;
@@ -628,8 +659,8 @@ declare function Add({
628
659
  readonly children: (slice: ContactsAddSlice) => ReactNode;
629
660
  }): import("react/jsx-runtime").JSX.Element;
630
661
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
631
- declare const CapxulContacts: typeof Root$4 & {
632
- Summary: typeof Summary$1;
662
+ declare const CapxulContacts: typeof Root$6 & {
663
+ Summary: typeof Summary$3;
633
664
  List: typeof List;
634
665
  Add: typeof Add;
635
666
  };
@@ -653,6 +684,7 @@ type ActivityRow = {
653
684
  readonly counterpartyLabel: string;
654
685
  readonly amountDisplay: string;
655
686
  readonly signedAmountDisplay: string;
687
+ readonly currency: string;
656
688
  readonly createdAt: number;
657
689
  readonly ledgerKind: "Payment" | "Payout" | "Deposit";
658
690
  readonly paymentType: PaymentType;
@@ -666,6 +698,7 @@ type ActivityRow = {
666
698
  readonly counterpartyLabel: string;
667
699
  readonly amountDisplay: string;
668
700
  readonly signedAmountDisplay: string;
701
+ readonly currency: string;
669
702
  readonly createdAt: number;
670
703
  readonly classification: "movement_only_outflow";
671
704
  readonly phase: ActivityPhase;
@@ -777,7 +810,7 @@ interface CapxulActivityProps {
777
810
  readonly pageSize?: number;
778
811
  readonly children: ReactNode;
779
812
  }
780
- declare function Root$3({
813
+ declare function Root$5({
781
814
  actor,
782
815
  pageSize,
783
816
  children
@@ -788,7 +821,7 @@ declare function Root$3({
788
821
  * pre-fetched result cannot serve both. It still holds no logic and draws
789
822
  * nothing.
790
823
  */
791
- declare function Summary({
824
+ declare function Summary$2({
792
825
  window,
793
826
  children
794
827
  }: {
@@ -828,8 +861,8 @@ declare function Export({
828
861
  readonly children: (slice: ActivityExportSlice) => ReactNode;
829
862
  }): import("react/jsx-runtime").JSX.Element;
830
863
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
831
- declare const CapxulActivity: typeof Root$3 & {
832
- Summary: typeof Summary;
864
+ declare const CapxulActivity: typeof Root$5 & {
865
+ Summary: typeof Summary$2;
833
866
  Filters: typeof Filters;
834
867
  Search: typeof Search;
835
868
  Rows: typeof Rows;
@@ -903,13 +936,13 @@ interface CapxulSendMoneyProps {
903
936
  readonly onFailed: (error: CapxulError) => void;
904
937
  readonly children: ReactNode;
905
938
  }
906
- declare function Root$2({
939
+ declare function Root$4({
907
940
  actor,
908
941
  onSent,
909
942
  onFailed,
910
943
  children
911
944
  }: CapxulSendMoneyProps): import("react/jsx-runtime").JSX.Element;
912
- declare function Asset({
945
+ declare function Asset$1({
913
946
  children
914
947
  }: {
915
948
  readonly children: (slice: SendMoneyAssetSlice) => ReactNode;
@@ -924,17 +957,17 @@ declare function Recipient({
924
957
  }: {
925
958
  readonly children: (slice: SendMoneyRecipientSlice) => ReactNode;
926
959
  }): import("react/jsx-runtime").JSX.Element;
927
- declare function Actions({
960
+ declare function Actions$1({
928
961
  children
929
962
  }: {
930
963
  readonly children: (slice: SendMoneyActionsSlice) => ReactNode;
931
964
  }): import("react/jsx-runtime").JSX.Element;
932
965
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
933
- declare const CapxulSendMoney: typeof Root$2 & {
934
- Asset: typeof Asset;
966
+ declare const CapxulSendMoney: typeof Root$4 & {
967
+ Asset: typeof Asset$1;
935
968
  Amount: typeof Amount;
936
969
  Recipient: typeof Recipient;
937
- Actions: typeof Actions;
970
+ Actions: typeof Actions$1;
938
971
  };
939
972
  //#endregion
940
973
  //#region src/headless/access/org-member.d.ts
@@ -961,7 +994,7 @@ interface CapxulOrgMemberProps {
961
994
  readonly orgId: OrgId | string | undefined;
962
995
  readonly children: ReactNode;
963
996
  }
964
- declare function Root$1({
997
+ declare function Root$3({
965
998
  orgId,
966
999
  children
967
1000
  }: CapxulOrgMemberProps): import("react/jsx-runtime").JSX.Element;
@@ -984,7 +1017,7 @@ declare function Standing({
984
1017
  readonly children: (slice: OrgMemberStandingSlice) => ReactNode;
985
1018
  }): import("react/jsx-runtime").JSX.Element;
986
1019
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
987
- declare const CapxulOrgMember: typeof Root$1 & {
1020
+ declare const CapxulOrgMember: typeof Root$3 & {
988
1021
  Can: typeof Can;
989
1022
  Standing: typeof Standing;
990
1023
  };
@@ -1009,7 +1042,7 @@ interface CapxulDashboardAccessProps {
1009
1042
  readonly scope: DashboardScope;
1010
1043
  readonly children: ReactNode;
1011
1044
  }
1012
- declare function Root({
1045
+ declare function Root$2({
1013
1046
  scope,
1014
1047
  children
1015
1048
  }: CapxulDashboardAccessProps): import("react/jsx-runtime").JSX.Element;
@@ -1035,13 +1068,204 @@ declare function Granted({
1035
1068
  readonly children?: ReactNode;
1036
1069
  }): import("react/jsx-runtime").JSX.Element | null;
1037
1070
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
1038
- declare const CapxulDashboardAccess: typeof Root & {
1071
+ declare const CapxulDashboardAccess: typeof Root$2 & {
1039
1072
  Checking: typeof Checking;
1040
1073
  Error: typeof DashboardError;
1041
1074
  Redirect: typeof Redirect;
1042
1075
  Granted: typeof Granted;
1043
1076
  };
1044
1077
  //#endregion
1078
+ //#region src/headless/payroll/use-payroll.d.ts
1079
+ interface PayrollGroupRow {
1080
+ readonly id: PayrollGroupId;
1081
+ readonly name: string;
1082
+ /** A stored display preference; the app narrows it to its own DS union. */
1083
+ readonly tone: string;
1084
+ readonly memberCount: number;
1085
+ /** `formatMoney` over the amounts the employer typed on this group. */
1086
+ readonly totalDisplay: string;
1087
+ readonly members: readonly {
1088
+ /** The `partyId` — the stable id (ruling Q1), never an email. */readonly recipientId: string;
1089
+ readonly amount: string;
1090
+ readonly currency: CurrencyCode;
1091
+ }[];
1092
+ }
1093
+ interface PayrollSummarySlice {
1094
+ readonly walletBalanceDisplay: string | null;
1095
+ readonly paidThisMonthDisplay: string | null;
1096
+ readonly isLoading: boolean;
1097
+ readonly error: CapxulError | null;
1098
+ }
1099
+ interface PayrollGroupsSlice {
1100
+ readonly groups: readonly PayrollGroupRow[];
1101
+ readonly save: (input: PayrollGroupInput) => Promise<CapxulResult<PayrollGroupRow>>;
1102
+ readonly remove: (id: PayrollGroupId) => Promise<CapxulResult<void>>;
1103
+ readonly isSaving: boolean;
1104
+ readonly isLoading: boolean;
1105
+ readonly error: CapxulError | null;
1106
+ }
1107
+ //#endregion
1108
+ //#region src/headless/payroll/payroll.d.ts
1109
+ interface CapxulPayrollProps {
1110
+ readonly orgId: OrgId | undefined;
1111
+ readonly children: ReactNode;
1112
+ }
1113
+ declare function Root$1({
1114
+ orgId,
1115
+ children
1116
+ }: CapxulPayrollProps): import("react/jsx-runtime").JSX.Element;
1117
+ declare function Summary$1({
1118
+ children
1119
+ }: {
1120
+ readonly children: (slice: PayrollSummarySlice) => ReactNode;
1121
+ }): import("react/jsx-runtime").JSX.Element;
1122
+ declare function Groups({
1123
+ children
1124
+ }: {
1125
+ readonly children: (slice: PayrollGroupsSlice) => ReactNode;
1126
+ }): import("react/jsx-runtime").JSX.Element;
1127
+ /**
1128
+ * The compound shape the app's own design system already uses (`StatusTabs`).
1129
+ * There is NO `.Runs` part (ruling Q6): no shipped region has the right shape
1130
+ * for a run list, and a part without a production caller may not ship.
1131
+ */
1132
+ declare const CapxulPayroll: typeof Root$1 & {
1133
+ Summary: typeof Summary$1;
1134
+ Groups: typeof Groups;
1135
+ };
1136
+ //#endregion
1137
+ //#region src/headless/payroll/reads.d.ts
1138
+ /**
1139
+ * One payable person, as the run composer and the group sheet see them.
1140
+ *
1141
+ * `id` is the `PartyId` — the stable key ADR-0022 R1 exists to provide, and the
1142
+ * end of the email-keyed recipient ids the deleted app hook minted.
1143
+ */
1144
+ interface PayrollRecipientOption {
1145
+ readonly id: string;
1146
+ /** The party's real display name, never an email local-part. */
1147
+ readonly name: string;
1148
+ readonly email: string | null;
1149
+ }
1150
+ //#endregion
1151
+ //#region src/headless/payroll/use-payroll-run.d.ts
1152
+ /**
1153
+ * Refusal CODES, never sentences (ADR-0023 R1). `blockedReason` names the FIRST
1154
+ * false fact in the fixed order of the contract's seven-row table, so the same
1155
+ * composer state always yields the same code.
1156
+ */
1157
+ type CapxulPayrollRunBlockedReason = "signer-not-ready" | "no-source" | "ambiguous-source" | "no-asset" | "no-recipients" | "amount-invalid" | "insufficient-funds";
1158
+ interface PayrollRunGroupOption {
1159
+ readonly id: PayrollGroupId;
1160
+ readonly label: string;
1161
+ /** The member count as text — the app supplies any word beside it. */
1162
+ readonly badgeLabel: string;
1163
+ readonly recipientIds: readonly string[];
1164
+ }
1165
+ interface PayrollRunRecipientsSlice {
1166
+ readonly options: readonly PayrollRecipientOption[];
1167
+ readonly groups: readonly PayrollRunGroupOption[];
1168
+ readonly selected: readonly string[];
1169
+ readonly toggle: (id: string) => void;
1170
+ readonly remove: (id: string) => void;
1171
+ readonly isLoading: boolean;
1172
+ readonly error: CapxulError | null;
1173
+ }
1174
+ interface PayrollRunAmountEntry {
1175
+ readonly recipientId: string;
1176
+ readonly name: string;
1177
+ readonly value: string;
1178
+ readonly change: (text: string) => void;
1179
+ /** The `parseMoney` verdict as a closed code; the app maps it to copy. */
1180
+ readonly error: MoneyParseErrorReason | null;
1181
+ /** True while the value is one we seeded and the employer has not edited. */
1182
+ readonly prefilled: boolean;
1183
+ /** The treasury asset's currency — the one-option dropdown stays. */
1184
+ readonly currency: CurrencyCode;
1185
+ }
1186
+ interface PayrollRunAmountsSlice {
1187
+ readonly entries: readonly PayrollRunAmountEntry[];
1188
+ }
1189
+ /** The SAME slice shape as `CapxulSendMoney.Asset` — the cross-item rule. */
1190
+ type PayrollRunAssetSlice = SendMoneyAssetSlice;
1191
+ interface PayrollRunSummarySlice {
1192
+ readonly recipientCount: number;
1193
+ /** Null until every selected amount parses. */
1194
+ readonly totalDisplay: string | null;
1195
+ readonly balanceAfterDisplay: string | null;
1196
+ readonly funds: "available" | "insufficient" | "unknown";
1197
+ }
1198
+ interface PayrollRunActionsSlice {
1199
+ readonly submit: () => void;
1200
+ readonly isSubmitting: boolean;
1201
+ readonly blocked: boolean;
1202
+ readonly blockedReason: CapxulPayrollRunBlockedReason | null;
1203
+ }
1204
+ interface PayrollRunPrefill {
1205
+ /** `partyId`s — how a group card opens pay-now pre-filled. */
1206
+ readonly recipientIds: readonly string[];
1207
+ readonly amounts?: readonly {
1208
+ readonly recipientId: string;
1209
+ readonly amount: string;
1210
+ }[];
1211
+ }
1212
+ interface SentPayrollRun {
1213
+ readonly id: PayrollRunId;
1214
+ readonly totalDisplay: string;
1215
+ readonly recipientCount: number;
1216
+ }
1217
+ //#endregion
1218
+ //#region src/headless/payroll/payroll-run.d.ts
1219
+ interface CapxulPayrollRunProps {
1220
+ readonly orgId: OrgId | undefined;
1221
+ /** How a group card opens pay-now pre-filled — today's group-context merge. */
1222
+ readonly prefill?: PayrollRunPrefill;
1223
+ readonly onRun: (run: SentPayrollRun) => void;
1224
+ /** ADR-0023 R1: the app maps `error.code` to its own copy; no SDK sentence. */
1225
+ readonly onFailed: (error: CapxulError) => void;
1226
+ readonly children: ReactNode;
1227
+ }
1228
+ declare function Root({
1229
+ orgId,
1230
+ prefill,
1231
+ onRun,
1232
+ onFailed,
1233
+ children
1234
+ }: CapxulPayrollRunProps): import("react/jsx-runtime").JSX.Element;
1235
+ declare function Recipients({
1236
+ children
1237
+ }: {
1238
+ readonly children: (slice: PayrollRunRecipientsSlice) => ReactNode;
1239
+ }): import("react/jsx-runtime").JSX.Element;
1240
+ declare function Amounts({
1241
+ children
1242
+ }: {
1243
+ readonly children: (slice: PayrollRunAmountsSlice) => ReactNode;
1244
+ }): import("react/jsx-runtime").JSX.Element;
1245
+ declare function Asset({
1246
+ children
1247
+ }: {
1248
+ readonly children: (slice: PayrollRunAssetSlice) => ReactNode;
1249
+ }): import("react/jsx-runtime").JSX.Element;
1250
+ declare function Summary({
1251
+ children
1252
+ }: {
1253
+ readonly children: (slice: PayrollRunSummarySlice) => ReactNode;
1254
+ }): import("react/jsx-runtime").JSX.Element;
1255
+ declare function Actions({
1256
+ children
1257
+ }: {
1258
+ readonly children: (slice: PayrollRunActionsSlice) => ReactNode;
1259
+ }): import("react/jsx-runtime").JSX.Element;
1260
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
1261
+ declare const CapxulPayrollRun: typeof Root & {
1262
+ Recipients: typeof Recipients;
1263
+ Amounts: typeof Amounts;
1264
+ Asset: typeof Asset;
1265
+ Summary: typeof Summary;
1266
+ Actions: typeof Actions;
1267
+ };
1268
+ //#endregion
1045
1269
  //#region src/internal/reactivity-keys.d.ts
1046
1270
  declare const capxulKeys: {
1047
1271
  root: readonly ["capxul"];
@@ -1061,6 +1285,8 @@ declare const capxulKeys: {
1061
1285
  orgLifecycle: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "lifecycle"];
1062
1286
  contacts: (scope: string) => readonly ["capxul", "contacts", string];
1063
1287
  contactsList: (scope: string, includeHidden: boolean) => readonly ["capxul", "contacts", string, "all" | "visible"];
1288
+ payrollRuns: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "payroll", "runs"];
1289
+ payrollGroups: (orgId: OrgId | undefined) => readonly ["capxul", "org", "pending" | OrgId, "payroll", "groups"];
1064
1290
  activity: readonly ["capxul", "activity"];
1065
1291
  activityDetail: (reference: ActivityReference | undefined, actor?: ActorReference | undefined) => readonly ["capxul", "activity", "self" | ActorReference, "pending" | ActivityReference];
1066
1292
  activitySummary: (actor?: ActorReference, window?: ActivityRange) => readonly ["capxul", "activity", "summary", "self" | ActorReference, "all" | ActivityRange];
@@ -1069,4 +1295,4 @@ declare const capxulKeys: {
1069
1295
  payment: (paymentId: string | undefined) => readonly ["capxul", "payments", string];
1070
1296
  };
1071
1297
  //#endregion
1072
- 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, 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 CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, 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 PendingAuthState, type ProfileDetails, type ProfileDraft, type ProfileSlotProps, type ReadyDestination, type RetryAction, type SendActor, type SendMoneyActionsSlice, type SendMoneyAmountSlice, type SendMoneyAssetError, type SendMoneyAssetOption, type SendMoneyAssetSlice, type SendMoneyRecipientMethod, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendResult, type SentPayment, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, 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 UseCapxulUsernameAvailabilityReturn, type UsernameAvailability, 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, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
1298
+ 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 CreateOrganizationSubmission, type CsvExport, type DashboardAccessErrorSlice, type DashboardAccessPhase, type DashboardAccessRedirectSlice, type DashboardScope, type Destination, type FaultedState, 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 SendMoneyRecipientMethod, type SendMoneyRecipientSlice, type SendMoneyRecipientStatus, type SendResult, type SentPayment, type SentPayrollRun, type SignedOutState, type Slot, type SummaryWindow, type UseCapxulAccountBalanceOptions, type UseCapxulAccountBalanceReturn, type UseCapxulAccountFundReturn, type UseCapxulCreateCommitmentReturn, type UseCapxulCreateOrgReturn, 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 UseCapxulUsernameAvailabilityReturn, type UsernameAvailability, 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, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  "use client";
2
- import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as capxulKeys, f as useCapxulClientOrNull, i as entered, l as useCapxulSend, n as CapxulOnboardingController, o as useCapxulDestination, p as useCapxul, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-DLBe4-OP.mjs";
2
+ import { a as useCapxulAuth, c as useCapxulIdentityOrNull, d as capxulKeys, f as useCapxulClientOrNull, i as entered, l as useCapxulSend, n as CapxulOnboardingController, o as useCapxulDestination, p as useCapxul, r as CapxulProvider, s as useCapxulIdentity, t as CapxulAuthenticationController, u as useCapxulTransitions } from "./controllers-DpScp8c5.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 { CapxulError, Errors, PAYMENT_DIRECTIONS, PAYMENT_STATUSES, fingerprintPaymentIntent, formatMoney, isCapxulError, isClaimed, isClaimed as isClaimed$1, isMoneyParseError, isRestoring, isRestoring as isRestoring$1, parseMoney, paymentPhase, resolveIdentityDestination } from "@capxul/sdk";
@@ -1014,7 +1014,7 @@ function useContactsContext() {
1014
1014
  if (engine === null) throw new Error("CapxulContacts parts must be used inside <CapxulContacts>");
1015
1015
  return engine;
1016
1016
  }
1017
- function Root$4({ actor, onAdded, onFailed, children }) {
1017
+ function Root$6({ actor, onAdded, onFailed, children }) {
1018
1018
  const engine = useContacts({
1019
1019
  actor,
1020
1020
  onAdded,
@@ -1025,7 +1025,7 @@ function Root$4({ actor, onAdded, onFailed, children }) {
1025
1025
  children
1026
1026
  });
1027
1027
  }
1028
- function Summary$1({ children }) {
1028
+ function Summary$3({ children }) {
1029
1029
  return /* @__PURE__ */ jsx(Fragment, { children: children(useContactsSummary(useContactsContext())) });
1030
1030
  }
1031
1031
  function List({ limit, show, children }) {
@@ -1038,8 +1038,8 @@ function Add({ children }) {
1038
1038
  return /* @__PURE__ */ jsx(Fragment, { children: children(useContactsContext().add) });
1039
1039
  }
1040
1040
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
1041
- const CapxulContacts = Object.assign(Root$4, {
1042
- Summary: Summary$1,
1041
+ const CapxulContacts = Object.assign(Root$6, {
1042
+ Summary: Summary$3,
1043
1043
  List,
1044
1044
  Add
1045
1045
  });
@@ -1053,7 +1053,7 @@ const CapxulContacts = Object.assign(Root$4, {
1053
1053
  * the app an error VALUE carrying a code and the app writes the sentence
1054
1054
  * (ADR-0023).
1055
1055
  */
1056
- function asCapxulError(error) {
1056
+ function asCapxulError$1(error) {
1057
1057
  if (error === null) return null;
1058
1058
  return isCapxulError(error) ? error : Errors.unknown(error);
1059
1059
  }
@@ -1163,7 +1163,7 @@ function useActivityDetail(reference, actor) {
1163
1163
  saveMemo,
1164
1164
  isSavingMemo: annotate.isPending,
1165
1165
  isLoading: enabled && detail.isLoading,
1166
- error: asCapxulError(detail.error) ?? annotate.error ?? null
1166
+ error: asCapxulError$1(detail.error) ?? annotate.error ?? null
1167
1167
  };
1168
1168
  }
1169
1169
  //#endregion
@@ -1299,7 +1299,7 @@ function useActivitySummary(actor, window) {
1299
1299
  pending: null,
1300
1300
  count: summary.data?.count ?? 0,
1301
1301
  isLoading,
1302
- error: asCapxulError(summary.error)
1302
+ error: asCapxulError$1(summary.error)
1303
1303
  };
1304
1304
  const display = (raw) => formatMoney({
1305
1305
  currency: bucket.currency,
@@ -1314,7 +1314,7 @@ function useActivitySummary(actor, window) {
1314
1314
  pending: display(bucket.pendingIn),
1315
1315
  count: summary.data?.count ?? 0,
1316
1316
  isLoading,
1317
- error: asCapxulError(summary.error)
1317
+ error: asCapxulError$1(summary.error)
1318
1318
  };
1319
1319
  }
1320
1320
  //#endregion
@@ -1349,6 +1349,7 @@ function toActivityRow(item, actor) {
1349
1349
  counterpartyLabel: item.counterpartyLabel,
1350
1350
  amountDisplay,
1351
1351
  signedAmountDisplay,
1352
+ currency: item.amount.currency,
1352
1353
  createdAt: item.createdAt,
1353
1354
  classification: item.classification,
1354
1355
  phase: MOVEMENT_PHASE,
@@ -1368,6 +1369,7 @@ function toActivityRow(item, actor) {
1368
1369
  counterpartyLabel: item.counterpartyLabel,
1369
1370
  amountDisplay,
1370
1371
  signedAmountDisplay,
1372
+ currency: item.amount.currency,
1371
1373
  createdAt: item.createdAt,
1372
1374
  ledgerKind: item.ledgerKind,
1373
1375
  paymentType: item.paymentType,
@@ -1620,7 +1622,7 @@ function useActivity(input) {
1620
1622
  rows: {
1621
1623
  rows,
1622
1624
  isLoading: query.isLoading,
1623
- error: asCapxulError(query.error),
1625
+ error: asCapxulError$1(query.error),
1624
1626
  retry,
1625
1627
  observedAt: pages === void 0 ? null : pages[pages.length - 1]?.observedAt ?? null
1626
1628
  },
@@ -1644,7 +1646,7 @@ function useActivityContext() {
1644
1646
  if (engine === null) throw new Error("CapxulActivity parts must be used inside <CapxulActivity>");
1645
1647
  return engine;
1646
1648
  }
1647
- function Root$3({ actor, pageSize, children }) {
1649
+ function Root$5({ actor, pageSize, children }) {
1648
1650
  const engine = useActivity({
1649
1651
  ...actor === void 0 ? {} : { actor },
1650
1652
  ...pageSize === void 0 ? {} : { pageSize }
@@ -1660,7 +1662,7 @@ function Root$3({ actor, pageSize, children }) {
1660
1662
  * pre-fetched result cannot serve both. It still holds no logic and draws
1661
1663
  * nothing.
1662
1664
  */
1663
- function Summary({ window = "all", children }) {
1665
+ function Summary$2({ window = "all", children }) {
1664
1666
  return /* @__PURE__ */ jsx(Fragment, { children: children(useActivitySummary(useActivityContext().actor, window)) });
1665
1667
  }
1666
1668
  function Filters({ children }) {
@@ -1694,8 +1696,8 @@ function Export({ children }) {
1694
1696
  return /* @__PURE__ */ jsx(Fragment, { children: children(useActivityContext().csv) });
1695
1697
  }
1696
1698
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
1697
- const CapxulActivity = Object.assign(Root$3, {
1698
- Summary,
1699
+ const CapxulActivity = Object.assign(Root$5, {
1700
+ Summary: Summary$2,
1699
1701
  Filters,
1700
1702
  Search,
1701
1703
  Rows,
@@ -1866,7 +1868,7 @@ function useSendMoneyContext() {
1866
1868
  if (engine === null) throw new Error("CapxulSendMoney parts must be used inside <CapxulSendMoney>");
1867
1869
  return engine;
1868
1870
  }
1869
- function Root$2({ actor, onSent, onFailed, children }) {
1871
+ function Root$4({ actor, onSent, onFailed, children }) {
1870
1872
  const engine = useSendMoney({
1871
1873
  actor,
1872
1874
  onSent,
@@ -1877,7 +1879,7 @@ function Root$2({ actor, onSent, onFailed, children }) {
1877
1879
  children
1878
1880
  });
1879
1881
  }
1880
- function Asset({ children }) {
1882
+ function Asset$1({ children }) {
1881
1883
  return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().asset) });
1882
1884
  }
1883
1885
  function Amount({ children }) {
@@ -1886,15 +1888,15 @@ function Amount({ children }) {
1886
1888
  function Recipient({ children }) {
1887
1889
  return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().recipient) });
1888
1890
  }
1889
- function Actions({ children }) {
1891
+ function Actions$1({ children }) {
1890
1892
  return /* @__PURE__ */ jsx(Fragment, { children: children(useSendMoneyContext().actions) });
1891
1893
  }
1892
1894
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
1893
- const CapxulSendMoney = Object.assign(Root$2, {
1894
- Asset,
1895
+ const CapxulSendMoney = Object.assign(Root$4, {
1896
+ Asset: Asset$1,
1895
1897
  Amount,
1896
1898
  Recipient,
1897
- Actions
1899
+ Actions: Actions$1
1898
1900
  });
1899
1901
  //#endregion
1900
1902
  //#region src/headless/access/org-member.tsx
@@ -2005,7 +2007,7 @@ function useOrgMemberContext() {
2005
2007
  if (state === null) throw new Error("CapxulOrgMember parts must be used inside <CapxulOrgMember>");
2006
2008
  return state;
2007
2009
  }
2008
- function Root$1({ orgId, children }) {
2010
+ function Root$3({ orgId, children }) {
2009
2011
  const state = useOrgMember(orgId);
2010
2012
  return /* @__PURE__ */ jsx(OrgMemberContext.Provider, {
2011
2013
  value: state,
@@ -2025,7 +2027,7 @@ function Standing({ children }) {
2025
2027
  return /* @__PURE__ */ jsx(Fragment, { children: children(useOrgMemberContext().standing) });
2026
2028
  }
2027
2029
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
2028
- const CapxulOrgMember = Object.assign(Root$1, {
2030
+ const CapxulOrgMember = Object.assign(Root$3, {
2029
2031
  Can,
2030
2032
  Standing
2031
2033
  });
@@ -2172,7 +2174,7 @@ function usePart(phase) {
2172
2174
  }, [placed, phase]);
2173
2175
  return state.phase === phase ? state : null;
2174
2176
  }
2175
- function Root({ scope, children }) {
2177
+ function Root$2({ scope, children }) {
2176
2178
  const state = useDashboardAccess(scope);
2177
2179
  const [placed] = useState(() => /* @__PURE__ */ new Set());
2178
2180
  const value = useMemo(() => ({
@@ -2210,11 +2212,591 @@ function Granted({ children }) {
2210
2212
  return usePart("granted") === null ? null : /* @__PURE__ */ jsx(Fragment, { children });
2211
2213
  }
2212
2214
  /** The compound shape the app's own design system already uses (`StatusTabs`). */
2213
- const CapxulDashboardAccess = Object.assign(Root, {
2215
+ const CapxulDashboardAccess = Object.assign(Root$2, {
2214
2216
  Checking,
2215
2217
  Error: DashboardError,
2216
2218
  Redirect,
2217
2219
  Granted
2218
2220
  });
2219
2221
  //#endregion
2220
- export { CapxulActivity, CapxulAuthenticationController, CapxulContacts, CapxulDashboardAccess, CapxulOnboardingController, CapxulOrgMember, 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, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
2222
+ //#region src/headless/payroll/money.ts
2223
+ /** `{ value: "12.34", decimals: 6 }` → `12340000n`. */
2224
+ function toMinorUnits(money) {
2225
+ const [whole = "0", fraction = ""] = money.value.split(".");
2226
+ return BigInt(`${whole}${fraction.padEnd(money.decimals, "0")}`);
2227
+ }
2228
+ const TYPED_AMOUNT = /^(-?)(\d+)(?:\.(\d+))?$/;
2229
+ /**
2230
+ * Σ of the employer's TYPED amounts on a saved group — a DISPLAY total.
2231
+ *
2232
+ * A group is a draft, so its amounts were never required to parse (backend
2233
+ * `payroll/groups.ts` validates the name and the recipients, never the money).
2234
+ * What cannot be read is skipped rather than poisoning the card's total, and
2235
+ * the widest fraction any member typed sets the scale so nothing rounds away.
2236
+ */
2237
+ function sumTypedAmounts(amounts, currency) {
2238
+ const parsed = amounts.map((amount) => TYPED_AMOUNT.exec(amount.trim().replaceAll(",", ""))).filter((match) => match !== null);
2239
+ const decimals = parsed.reduce((widest, match) => Math.max(widest, (match[3] ?? "").length), 0);
2240
+ return fromMinorUnits(parsed.reduce((sum, match) => {
2241
+ const scaled = BigInt(`${match[2] ?? "0"}${(match[3] ?? "").padEnd(decimals, "0")}`);
2242
+ return match[1] === "-" ? sum - scaled : sum + scaled;
2243
+ }, 0n), {
2244
+ currency,
2245
+ decimals
2246
+ });
2247
+ }
2248
+ /** The inverse, so a summed total can be formatted by the shipped `formatMoney`. */
2249
+ function fromMinorUnits(raw, asset) {
2250
+ const negative = raw < 0n;
2251
+ const digits = (negative ? -raw : raw).toString().padStart(asset.decimals + 1, "0");
2252
+ const whole = digits.slice(0, digits.length - asset.decimals);
2253
+ const fraction = asset.decimals === 0 ? "" : `.${digits.slice(digits.length - asset.decimals)}`;
2254
+ return {
2255
+ currency: asset.currency,
2256
+ value: `${negative ? "-" : ""}${whole}${fraction}`,
2257
+ decimals: asset.decimals
2258
+ };
2259
+ }
2260
+ //#endregion
2261
+ //#region src/headless/payroll/reads.ts
2262
+ function toRecipientOption(entry) {
2263
+ return {
2264
+ id: entry.id,
2265
+ name: entry.label,
2266
+ email: entry.label.includes("@") ? entry.label : null
2267
+ };
2268
+ }
2269
+ /**
2270
+ * The roster: active `employed` edges ∪ org members, deduped by party
2271
+ * (ruling Q1 = C).
2272
+ *
2273
+ * The organization address book computes exactly that union server-side —
2274
+ * members accumulate from `orgMembers`, employment is PROJECTED from open
2275
+ * `employed` edges, and both land in ONE map keyed by party
2276
+ * (`financialOps/addressBook.ts`). Contact edges live in the same book and are
2277
+ * not the roster, so the two relationships the roster is made of are the
2278
+ * filter.
2279
+ */
2280
+ function useOrgRoster(orgId) {
2281
+ const client = useCapxulClientOrNull();
2282
+ const query = useQuery({
2283
+ queryKey: capxulKeys.contactsList(orgId ?? "pending", false),
2284
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.addressBook.list", orgId).addressBook.list({ includeHidden: false })),
2285
+ enabled: client !== null && orgId !== void 0
2286
+ });
2287
+ const entries = query.data;
2288
+ return useMemo(() => {
2289
+ const roster = (entries ?? []).filter((entry) => entry.relationship.includes("member") || entry.relationship.includes("employed"));
2290
+ return {
2291
+ options: roster.map(toRecipientOption),
2292
+ refs: new Map(roster.map((entry) => [entry.id, entry.ref])),
2293
+ isLoading: orgId !== void 0 && entries === void 0 && query.error === null,
2294
+ error: query.error
2295
+ };
2296
+ }, [
2297
+ entries,
2298
+ orgId,
2299
+ query.error
2300
+ ]);
2301
+ }
2302
+ function usePayrollGroups(orgId) {
2303
+ const client = useCapxulClientOrNull();
2304
+ return useQuery({
2305
+ queryKey: capxulKeys.payrollGroups(orgId),
2306
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.payroll.groups.list", orgId).payroll.groups.list()),
2307
+ enabled: client !== null && orgId !== void 0
2308
+ });
2309
+ }
2310
+ function usePayrollRuns(orgId) {
2311
+ const client = useCapxulClientOrNull();
2312
+ return useQuery({
2313
+ queryKey: capxulKeys.payrollRuns(orgId),
2314
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.payroll.runs", orgId).payroll.runs()),
2315
+ enabled: client !== null && orgId !== void 0
2316
+ });
2317
+ }
2318
+ function useOrgTreasury(orgId) {
2319
+ const client = useCapxulClientOrNull();
2320
+ return useQuery({
2321
+ queryKey: capxulKeys.orgTreasury(orgId),
2322
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.treasury", orgId).treasury()),
2323
+ enabled: client !== null && orgId !== void 0
2324
+ });
2325
+ }
2326
+ /**
2327
+ * The caller's own standing, read for its Budgets alone (ruling Q2 grades
2328
+ * them). Keyed as `CapxulOrgMember` keys it, so a payroll screen inside a
2329
+ * `.Can` wrapper reads `org(id).me()` once.
2330
+ */
2331
+ function useOrgMe(orgId) {
2332
+ const client = useCapxulClientOrNull();
2333
+ return useQuery({
2334
+ queryKey: capxulKeys.orgMe(orgId),
2335
+ queryFn: async () => unwrapCapxulResult(await scopedClient(client, "org.me", orgId).me()),
2336
+ enabled: client !== null && orgId !== void 0
2337
+ });
2338
+ }
2339
+ /**
2340
+ * The org-scoped bundle inside a query or mutation function. Every caller gates
2341
+ * on `orgId !== undefined`, so the second throw is only reachable from a
2342
+ * mutation fired while the provider is still bootstrapping.
2343
+ */
2344
+ function scopedClient(client, method, orgId) {
2345
+ const bootstrapped = requireBootstrappedClient(client, method);
2346
+ if (orgId === void 0) throw Errors.invalidInput("orgId", `required for ${method}`);
2347
+ return bootstrapped.org(orgId);
2348
+ }
2349
+ //#endregion
2350
+ //#region src/headless/payroll/use-payroll.ts
2351
+ /** Money reads the same way everywhere on this screen: amount then code. */
2352
+ const GRAMMAR$1 = { grammar: "code" };
2353
+ function toPayrollGroupRow(group) {
2354
+ const currency = new Set(group.members.map((member) => member.currency)).size === 1 ? group.members[0]?.currency : void 0;
2355
+ return {
2356
+ id: group.id,
2357
+ name: group.name,
2358
+ tone: group.tone,
2359
+ memberCount: group.members.length,
2360
+ totalDisplay: currency === void 0 ? "" : formatMoney(sumTypedAmounts(group.members.map((member) => member.amount), currency), GRAMMAR$1),
2361
+ members: group.members.map((member) => ({
2362
+ recipientId: member.partyId,
2363
+ amount: member.amount,
2364
+ currency: member.currency
2365
+ }))
2366
+ };
2367
+ }
2368
+ /**
2369
+ * The validity `buildOrganizationPayrollGroupRecord` applied in the browser
2370
+ * (payroll groups hook `:57-82`) — a trimmed name, at least one deduped
2371
+ * recipient — checked here so an invalid group never costs a round trip. The
2372
+ * backend re-checks it; this is honest UX, not the authority.
2373
+ *
2374
+ * ADR-0023 R1: the refusal is a CODE, never a toast sentence.
2375
+ */
2376
+ function invalidGroup(input) {
2377
+ if (input.name.trim().length === 0) return Errors.invalidInput("name", "must not be empty");
2378
+ const deduped = new Set(input.members.map((member) => member.partyId));
2379
+ deduped.delete("");
2380
+ return deduped.size === 0 ? Errors.invalidInput("members", "must not be empty") : null;
2381
+ }
2382
+ function usePayroll(orgId) {
2383
+ const client = useCapxulClientOrNull();
2384
+ const queryClient = useQueryClient();
2385
+ const treasury = useOrgTreasury(orgId);
2386
+ const runs = usePayrollRuns(orgId);
2387
+ const groups = usePayrollGroups(orgId);
2388
+ const write = useMutation({
2389
+ mutationFn: async (command) => {
2390
+ const payroll = scopedClient(client, `org.payroll.groups.${command.kind}`, orgId).payroll;
2391
+ if (command.kind === "remove") {
2392
+ unwrapCapxulResult(await payroll.groups.remove(command.id));
2393
+ return null;
2394
+ }
2395
+ return unwrapCapxulResult(await payroll.groups.save(command.input));
2396
+ },
2397
+ onSettled: useCallback(() => queryClient.invalidateQueries({ queryKey: capxulKeys.payrollGroups(orgId) }), [orgId, queryClient])
2398
+ });
2399
+ const mutateAsync = write.mutateAsync;
2400
+ const save = useCallback(async (input) => {
2401
+ const refusal = invalidGroup(input);
2402
+ if (refusal !== null) return {
2403
+ ok: false,
2404
+ error: refusal
2405
+ };
2406
+ try {
2407
+ const saved = await mutateAsync({
2408
+ kind: "save",
2409
+ input
2410
+ });
2411
+ return saved === null ? {
2412
+ ok: false,
2413
+ error: Errors.unknown()
2414
+ } : {
2415
+ ok: true,
2416
+ value: toPayrollGroupRow(saved)
2417
+ };
2418
+ } catch (cause) {
2419
+ return {
2420
+ ok: false,
2421
+ error: asCapxulError(cause)
2422
+ };
2423
+ }
2424
+ }, [mutateAsync]);
2425
+ const remove = useCallback(async (id) => {
2426
+ try {
2427
+ await mutateAsync({
2428
+ kind: "remove",
2429
+ id
2430
+ });
2431
+ return {
2432
+ ok: true,
2433
+ value: void 0
2434
+ };
2435
+ } catch (cause) {
2436
+ return {
2437
+ ok: false,
2438
+ error: asCapxulError(cause)
2439
+ };
2440
+ }
2441
+ }, [mutateAsync]);
2442
+ const rows = useMemo(() => (groups.data ?? []).map(toPayrollGroupRow), [groups.data]);
2443
+ const started = orgId !== void 0;
2444
+ return {
2445
+ summary: {
2446
+ walletBalanceDisplay: treasury.data === void 0 ? null : formatMoney(treasury.data.available, GRAMMAR$1),
2447
+ paidThisMonthDisplay: runs.data === void 0 ? null : formatMoney(runs.data.settledThisMonth, GRAMMAR$1),
2448
+ isLoading: started && (treasury.data === void 0 && treasury.error === null || runs.data === void 0 && runs.error === null),
2449
+ error: treasury.error ?? runs.error
2450
+ },
2451
+ groups: {
2452
+ groups: rows,
2453
+ save,
2454
+ remove,
2455
+ isSaving: write.isPending,
2456
+ isLoading: started && groups.data === void 0 && groups.error === null,
2457
+ error: groups.error
2458
+ }
2459
+ };
2460
+ }
2461
+ /**
2462
+ * React Query rejects with whatever the query function threw. Every throw on
2463
+ * this path is a `CapxulError` the SDK produced; anything else is a defect and
2464
+ * normalizes once, exactly as the facade boundary does.
2465
+ */
2466
+ function asCapxulError(cause) {
2467
+ return isCapxulError$1(cause) ? cause : Errors.unknown(cause);
2468
+ }
2469
+ function isCapxulError$1(cause) {
2470
+ return typeof cause === "object" && cause !== null && "code" in cause;
2471
+ }
2472
+ //#endregion
2473
+ //#region src/headless/payroll/payroll.tsx
2474
+ const PayrollContext = createContext(null);
2475
+ function usePayrollContext() {
2476
+ const engine = useContext(PayrollContext);
2477
+ if (engine === null) throw new Error("CapxulPayroll parts must be used inside <CapxulPayroll>");
2478
+ return engine;
2479
+ }
2480
+ function Root$1({ orgId, children }) {
2481
+ const engine = usePayroll(orgId);
2482
+ return /* @__PURE__ */ jsx(PayrollContext.Provider, {
2483
+ value: engine,
2484
+ children
2485
+ });
2486
+ }
2487
+ function Summary$1({ children }) {
2488
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollContext().summary) });
2489
+ }
2490
+ function Groups({ children }) {
2491
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollContext().groups) });
2492
+ }
2493
+ /**
2494
+ * The compound shape the app's own design system already uses (`StatusTabs`).
2495
+ * There is NO `.Runs` part (ruling Q6): no shipped region has the right shape
2496
+ * for a run list, and a part without a production caller may not ship.
2497
+ */
2498
+ const CapxulPayroll = Object.assign(Root$1, {
2499
+ Summary: Summary$1,
2500
+ Groups
2501
+ });
2502
+ //#endregion
2503
+ //#region src/headless/payroll/use-payroll-run.ts
2504
+ const GRAMMAR = { grammar: "code" };
2505
+ /**
2506
+ * The one place the composer states a currency it has not read yet. The token
2507
+ * dropdown holds exactly one option — the treasury's — so before that read
2508
+ * lands there is no currency to name, and naming a wrong one would be a fake
2509
+ * green on the money itself.
2510
+ */
2511
+ const CURRENCY_UNREAD = "";
2512
+ /**
2513
+ * WHICH run the composer is composing, by MEANING rather than by object shape.
2514
+ *
2515
+ * `recipientIds` order is meaning — it is the order `.Amounts` rows appear in.
2516
+ * The `amounts` order is not, so the key reads the seed `initialAmounts` will
2517
+ * actually build rather than the array it was handed: one collapse rule, in one
2518
+ * place, so the two can never disagree about a repeated recipient. A parent
2519
+ * that rebuilds an equivalent `prefill` therefore keeps its key, and the
2520
+ * employer's in-progress edits with it. An absent `prefill` and one that seeds
2521
+ * nothing open the same empty composer, so they share a key on purpose.
2522
+ */
2523
+ function composerIdentity(orgId, prefill) {
2524
+ const seeds = Object.entries(initialAmounts(prefill)).map(([recipientId, draft]) => `${recipientId}=${draft.value}`).sort();
2525
+ return [
2526
+ orgId ?? "",
2527
+ ...prefill?.recipientIds ?? [],
2528
+ "|",
2529
+ ...seeds
2530
+ ].join("\0");
2531
+ }
2532
+ /** Seeded from `prefill` on first render; the employer owns it after that. */
2533
+ function initialAmounts(prefill) {
2534
+ const seeded = {};
2535
+ for (const entry of prefill?.amounts ?? []) seeded[entry.recipientId] = {
2536
+ value: entry.amount,
2537
+ prefilled: true
2538
+ };
2539
+ return seeded;
2540
+ }
2541
+ function usePayrollRun(input) {
2542
+ const { orgId, prefill, onRun, onFailed } = input;
2543
+ const client = useCapxulClientOrNull();
2544
+ const queryClient = useQueryClient();
2545
+ const signerStatus = useSignerStatus(client);
2546
+ const roster = useOrgRoster(orgId);
2547
+ const groups = usePayrollGroups(orgId);
2548
+ const treasury = useOrgTreasury(orgId);
2549
+ const me = useOrgMe(orgId);
2550
+ const [selected, setSelected] = useState(() => prefill?.recipientIds ?? []);
2551
+ const [amounts, setAmounts] = useState(() => initialAmounts(prefill));
2552
+ const composerKey = composerIdentity(orgId, prefill);
2553
+ const [seededKey, setSeededKey] = useState(composerKey);
2554
+ if (seededKey !== composerKey) {
2555
+ setSeededKey(composerKey);
2556
+ setSelected(prefill?.recipientIds ?? []);
2557
+ setAmounts(initialAmounts(prefill));
2558
+ }
2559
+ const toggle = useCallback((id) => setSelected((current) => current.includes(id) ? current.filter((held) => held !== id) : [...current, id]), []);
2560
+ const remove = useCallback((id) => setSelected((current) => current.filter((held) => held !== id)), []);
2561
+ const change = useCallback((id, text) => {
2562
+ setAmounts((current) => ({
2563
+ ...current,
2564
+ [id]: {
2565
+ value: text,
2566
+ prefilled: false
2567
+ }
2568
+ }));
2569
+ }, []);
2570
+ const account = treasury.data ?? null;
2571
+ const assetOptions = useMemo(() => account === null ? [] : [{
2572
+ id: account.id,
2573
+ symbol: account.available.currency,
2574
+ availableDisplay: formatMoney(account.available, GRAMMAR)
2575
+ }], [account]);
2576
+ const [selectedAssetId, setSelectedAssetId] = useState(null);
2577
+ useEffect(() => {
2578
+ if (!assetOptions.some((option) => option.id === selectedAssetId)) setSelectedAssetId(assetOptions[0]?.id ?? null);
2579
+ }, [assetOptions, selectedAssetId]);
2580
+ const selectedAsset = assetOptions.find((option) => option.id === selectedAssetId) ?? null;
2581
+ const selectAsset = useCallback((id) => {
2582
+ setSelectedAssetId((current) => assetOptions.some((option) => option.id === id) ? id : current);
2583
+ }, [assetOptions]);
2584
+ const assetMoney = selectedAsset !== null && account !== null ? account.available : null;
2585
+ const named = useMemo(() => new Map(roster.options.map((option) => [option.id, option])), [roster.options]);
2586
+ const refs = roster.refs;
2587
+ const payableRefs = useMemo(() => {
2588
+ const resolved = [];
2589
+ for (const recipientId of selected) {
2590
+ const ref = refs.get(recipientId);
2591
+ if (ref === void 0) return null;
2592
+ resolved.push(ref);
2593
+ }
2594
+ return resolved;
2595
+ }, [refs, selected]);
2596
+ const entries = useMemo(() => selected.map((recipientId) => {
2597
+ const draft = amounts[recipientId];
2598
+ const value = draft?.value ?? "";
2599
+ const parsed = assetMoney === null || value.trim() === "" ? null : parseMoney(value, assetMoney);
2600
+ return {
2601
+ recipientId,
2602
+ name: named.get(recipientId)?.name ?? recipientId,
2603
+ value,
2604
+ change: (text) => change(recipientId, text),
2605
+ error: parsed !== null && isMoneyParseError(parsed) ? parsed.reason : null,
2606
+ prefilled: draft?.prefilled ?? false,
2607
+ currency: assetMoney?.currency ?? CURRENCY_UNREAD
2608
+ };
2609
+ }), [
2610
+ amounts,
2611
+ assetMoney,
2612
+ change,
2613
+ named,
2614
+ selected
2615
+ ]);
2616
+ const parsedAmounts = useMemo(() => {
2617
+ if (assetMoney === null || selected.length === 0) return null;
2618
+ const money = [];
2619
+ for (const recipientId of selected) {
2620
+ const parsed = parseMoney(amounts[recipientId]?.value ?? "", assetMoney);
2621
+ if (isMoneyParseError(parsed)) return null;
2622
+ money.push(parsed);
2623
+ }
2624
+ return money;
2625
+ }, [
2626
+ amounts,
2627
+ assetMoney,
2628
+ selected
2629
+ ]);
2630
+ const total = useMemo(() => parsedAmounts === null || assetMoney === null ? null : fromMinorUnits(parsedAmounts.reduce((sum, money) => sum + toMinorUnits(money), 0n), assetMoney), [assetMoney, parsedAmounts]);
2631
+ const availableRaw = assetMoney === null ? null : toMinorUnits(assetMoney);
2632
+ const totalRaw = total === null ? null : toMinorUnits(total);
2633
+ const funds = availableRaw === null || totalRaw === null ? "unknown" : totalRaw > availableRaw ? "insufficient" : "available";
2634
+ const budgets = me.data?.budgets ?? [];
2635
+ const blockedReason = firstFalseFact({
2636
+ signerReady: signerStatus === "ready",
2637
+ budgetCount: budgets.length,
2638
+ hasAsset: selectedAsset !== null,
2639
+ recipientCount: payableRefs === null ? 0 : selected.length,
2640
+ amountsParse: total !== null,
2641
+ funds
2642
+ });
2643
+ const authorize = useMutation({
2644
+ mutationFn: async (command) => {
2645
+ const runAt = Date.now();
2646
+ return unwrapCapxulResult(await scopedClient(client, "org.payroll.authorizeRun", orgId).payroll.authorizeRun({
2647
+ permissionId: command.permissionId,
2648
+ period: {
2649
+ start: runAt,
2650
+ end: runAt
2651
+ },
2652
+ items: command.items
2653
+ }));
2654
+ },
2655
+ onSettled: () => {
2656
+ queryClient.invalidateQueries({ queryKey: capxulKeys.payrollRuns(orgId) });
2657
+ }
2658
+ });
2659
+ const submitGate = useRef(false);
2660
+ const totalDisplay = total === null ? null : formatMoney(total, GRAMMAR);
2661
+ const authorizeMutate = authorize.mutate;
2662
+ const submit = useCallback(() => {
2663
+ const permissionId = budgets[0]?.id;
2664
+ if (blockedReason !== null || submitGate.current) return;
2665
+ if (permissionId === void 0 || totalDisplay === null || parsedAmounts === null) return;
2666
+ if (payableRefs === null) return;
2667
+ const recipientCount = selected.length;
2668
+ const items = [];
2669
+ for (const [index, recipientId] of selected.entries()) {
2670
+ const to = payableRefs[index];
2671
+ const parsed = parsedAmounts[index];
2672
+ if (to === void 0 || parsed === void 0) return;
2673
+ const raw = toMinorUnits(parsed).toString();
2674
+ items.push({
2675
+ to,
2676
+ partyId: recipientId,
2677
+ gross: raw,
2678
+ net: raw,
2679
+ adjustments: []
2680
+ });
2681
+ }
2682
+ submitGate.current = true;
2683
+ authorizeMutate({
2684
+ permissionId,
2685
+ items
2686
+ }, {
2687
+ onSuccess: (run) => onRun({
2688
+ id: run.id,
2689
+ totalDisplay,
2690
+ recipientCount
2691
+ }),
2692
+ onError: onFailed,
2693
+ onSettled: () => {
2694
+ submitGate.current = false;
2695
+ }
2696
+ });
2697
+ }, [
2698
+ authorizeMutate,
2699
+ blockedReason,
2700
+ budgets,
2701
+ onFailed,
2702
+ onRun,
2703
+ parsedAmounts,
2704
+ payableRefs,
2705
+ selected,
2706
+ totalDisplay
2707
+ ]);
2708
+ return {
2709
+ recipients: {
2710
+ options: roster.options,
2711
+ groups: (groups.data ?? []).map((group) => ({
2712
+ id: group.id,
2713
+ label: group.name,
2714
+ badgeLabel: String(group.members.length),
2715
+ recipientIds: group.members.map((member) => member.partyId)
2716
+ })),
2717
+ selected,
2718
+ toggle,
2719
+ remove,
2720
+ isLoading: roster.isLoading,
2721
+ error: roster.error ?? groups.error
2722
+ },
2723
+ amounts: { entries },
2724
+ asset: {
2725
+ options: assetOptions,
2726
+ selected: selectedAsset,
2727
+ select: selectAsset,
2728
+ error: treasury.error === null ? null : "read-failed"
2729
+ },
2730
+ summary: {
2731
+ recipientCount: selected.length,
2732
+ totalDisplay,
2733
+ balanceAfterDisplay: totalRaw === null || availableRaw === null || assetMoney === null ? null : formatMoney(fromMinorUnits(availableRaw - totalRaw, assetMoney), GRAMMAR),
2734
+ funds
2735
+ },
2736
+ actions: {
2737
+ submit,
2738
+ isSubmitting: authorize.isPending,
2739
+ blocked: blockedReason !== null,
2740
+ blockedReason
2741
+ }
2742
+ };
2743
+ }
2744
+ /**
2745
+ * The seven facts, in the ONE order the contract fixes. Exactly one code comes
2746
+ * out, and it is always the first thing that is false — so two problems never
2747
+ * race to name the button.
2748
+ */
2749
+ function firstFalseFact(facts) {
2750
+ if (!facts.signerReady) return "signer-not-ready";
2751
+ if (facts.budgetCount === 0) return "no-source";
2752
+ if (facts.budgetCount > 1) return "ambiguous-source";
2753
+ if (!facts.hasAsset) return "no-asset";
2754
+ if (facts.recipientCount === 0) return "no-recipients";
2755
+ if (!facts.amountsParse) return "amount-invalid";
2756
+ return facts.funds === "insufficient" ? "insufficient-funds" : null;
2757
+ }
2758
+ //#endregion
2759
+ //#region src/headless/payroll/payroll-run.tsx
2760
+ const PayrollRunContext = createContext(null);
2761
+ function usePayrollRunContext() {
2762
+ const engine = useContext(PayrollRunContext);
2763
+ if (engine === null) throw new Error("CapxulPayrollRun parts must be used inside <CapxulPayrollRun>");
2764
+ return engine;
2765
+ }
2766
+ function Root({ orgId, prefill, onRun, onFailed, children }) {
2767
+ const engine = usePayrollRun({
2768
+ orgId,
2769
+ prefill,
2770
+ onRun,
2771
+ onFailed
2772
+ });
2773
+ return /* @__PURE__ */ jsx(PayrollRunContext.Provider, {
2774
+ value: engine,
2775
+ children
2776
+ });
2777
+ }
2778
+ function Recipients({ children }) {
2779
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollRunContext().recipients) });
2780
+ }
2781
+ function Amounts({ children }) {
2782
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollRunContext().amounts) });
2783
+ }
2784
+ function Asset({ children }) {
2785
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollRunContext().asset) });
2786
+ }
2787
+ function Summary({ children }) {
2788
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollRunContext().summary) });
2789
+ }
2790
+ function Actions({ children }) {
2791
+ return /* @__PURE__ */ jsx(Fragment, { children: children(usePayrollRunContext().actions) });
2792
+ }
2793
+ /** The compound shape the app's own design system already uses (`StatusTabs`). */
2794
+ const CapxulPayrollRun = Object.assign(Root, {
2795
+ Recipients,
2796
+ Amounts,
2797
+ Asset,
2798
+ Summary,
2799
+ Actions
2800
+ });
2801
+ //#endregion
2802
+ 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, useCapxulHoldings, useCapxulIdentity, useCapxulImageUpload, useCapxulInviteMember, useCapxulOrgMembers, useCapxulOrgRoles, useCapxulOrgTreasury, useCapxulOrganizationPay, useCapxulOrganizationPayBatch, useCapxulOrgs, useCapxulPay, useCapxulPayment, useCapxulPayments, useCapxulPermission, useCapxulPermissionAssign, useCapxulPermissionChange, useCapxulPermissionCreate, useCapxulPermissionReplace, useCapxulPermissionRevoke, useCapxulPermissions, useCapxulProfile, useCapxulRedirectPayment, useCapxulSend, useCapxulTransitions, useCapxulUsernameAvailability };
@@ -1,4 +1,4 @@
1
- import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DLBe4-OP.mjs";
1
+ import { n as CapxulOnboardingController, r as CapxulProvider, t as CapxulAuthenticationController } from "../controllers-DpScp8c5.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": "2.4.0",
3
+ "version": "2.5.1",
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": "2.4.0"
29
+ "@capxul/sdk": "2.5.1"
30
30
  },
31
31
  "devDependencies": {
32
32
  "@tanstack/react-query": "^5.66.9",
@@ -42,8 +42,8 @@
42
42
  "react-dom": "^19.2.6",
43
43
  "vite-plus": "0.1.23",
44
44
  "vitest": "npm:@voidzero-dev/vite-plus-test@0.1.23",
45
- "@capxul/errors": "0.0.1",
46
- "@capxul/types": "0.2.0",
45
+ "@capxul/errors": "0.0.2",
46
+ "@capxul/types": "0.2.1",
47
47
  "@capxul/typescript-config": "0.0.0"
48
48
  },
49
49
  "peerDependencies": {