@capxul/sdk-react 0.0.0-rc-2cdddbb91

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.
@@ -0,0 +1,205 @@
1
+ import { ReactNode } from "react";
2
+ import { CapxulClient, CapxulError, CapxulErrorCode, IdentityDestination, IdentityEvent, IdentityProfileDetails, IdentityState, IdentityTransition, OrgLane, Readiness } from "@capxul/sdk";
3
+ //#region src/platform/identity-contract.d.ts
4
+ type Destination = IdentityDestination;
5
+ interface InvocationOptions {
6
+ readonly correlationId?: string;
7
+ readonly journeyId?: string;
8
+ readonly timeoutMs?: number;
9
+ readonly deadlineMs?: number;
10
+ readonly signal?: AbortSignal;
11
+ }
12
+ type SendResult = {
13
+ readonly ok: true;
14
+ readonly state: IdentityState;
15
+ } | {
16
+ readonly ok: false;
17
+ readonly refused: CapxulErrorCode;
18
+ readonly state: IdentityState;
19
+ };
20
+ type CapxulSend = (event: IdentityEvent, options?: InvocationOptions) => Promise<SendResult>;
21
+ type ProfileDetails = IdentityProfileDetails;
22
+ interface OrganizationDetails {
23
+ readonly name: string;
24
+ readonly handle: string;
25
+ readonly country: string;
26
+ readonly bio?: string;
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;
34
+ }
35
+ interface CreateOrganizationSubmission {
36
+ readonly profileDetails: ProfileDetails;
37
+ readonly organization: OrganizationDetails;
38
+ }
39
+ /** A refused facade call: its code, and the whole error when one was raised. */
40
+ type FacadeFailure = {
41
+ readonly ok: false;
42
+ readonly reason: CapxulErrorCode;
43
+ readonly error?: CapxulError;
44
+ };
45
+ type CreateOrganizationFailure = FacadeFailure & {
46
+ readonly error: CapxulError;
47
+ };
48
+ type EmptyResult = {
49
+ readonly ok: true;
50
+ } | FacadeFailure;
51
+ interface CapxulAuth {
52
+ readonly requestCode: (email: string, options?: InvocationOptions) => Promise<{
53
+ readonly ok: true;
54
+ readonly requestedAt: number;
55
+ } | FacadeFailure>;
56
+ readonly verifyCode: (otp: string, options?: InvocationOptions) => Promise<{
57
+ readonly ok: true;
58
+ readonly authUserId: string;
59
+ readonly profileComplete: boolean;
60
+ } | FacadeFailure>;
61
+ readonly signOut: (options?: InvocationOptions) => Promise<EmptyResult>;
62
+ readonly createOrganization: (submission: CreateOrganizationSubmission, options?: InvocationOptions) => Promise<{
63
+ readonly ok: true;
64
+ readonly orgId: string;
65
+ } | CreateOrganizationFailure>;
66
+ readonly completePersonal: (profileDetails: ProfileDetails, options?: InvocationOptions) => Promise<EmptyResult>;
67
+ readonly retry: (options?: InvocationOptions) => Promise<EmptyResult>;
68
+ }
69
+ type TransitionListener = (record: IdentityTransition, state: IdentityState) => void;
70
+ //#endregion
71
+ //#region src/access/controllers.d.ts
72
+ type Slot<P> = (props: P) => ReactNode;
73
+ type ActionResult = {
74
+ readonly ok: true;
75
+ } | {
76
+ readonly ok: false;
77
+ readonly reason: import("@capxul/sdk").CapxulErrorCode;
78
+ };
79
+ type ControllerAction = () => Promise<ActionResult>;
80
+ type RetryAction = (options: InvocationOptions) => Promise<ActionResult>;
81
+ type NavigationAction = () => void;
82
+ type SignedOutState = Extract<IdentityState, {
83
+ phase: "signed_out";
84
+ }>;
85
+ type OtpPendingState = Extract<IdentityState, {
86
+ phase: "otp_pending";
87
+ }>;
88
+ type PendingAuthState = Extract<IdentityState, {
89
+ phase: "restoring" | "otp_sending" | "otp_verifying" | "signing_out";
90
+ }>;
91
+ type FaultedState = Extract<IdentityState, {
92
+ phase: "faulted";
93
+ }>;
94
+ type AuthenticatedState = Extract<IdentityState, {
95
+ phase: "authenticated";
96
+ }>;
97
+ type AccountProgress = Exclude<Readiness, {
98
+ at: "failed";
99
+ } | {
100
+ at: "claimed";
101
+ }>;
102
+ type AccountFailure = Extract<Readiness, {
103
+ at: "failed";
104
+ }>;
105
+ type OrgProgress = OrgLane;
106
+ type OrgFailure = OrgLane;
107
+ type ReadyDestination = Extract<IdentityDestination, {
108
+ to: "dashboardPersonal" | "dashboardOrganization";
109
+ }>;
110
+ interface AuthenticationSlots {
111
+ readonly email: Slot<{
112
+ state: SignedOutState;
113
+ requestCode: CapxulAuth["requestCode"];
114
+ }>;
115
+ readonly otp: Slot<{
116
+ state: OtpPendingState;
117
+ verifyCode: CapxulAuth["verifyCode"];
118
+ back: ControllerAction;
119
+ }>;
120
+ readonly pending: Slot<{
121
+ state: PendingAuthState;
122
+ }>;
123
+ readonly failure: Slot<{
124
+ state: FaultedState;
125
+ recover: ControllerAction;
126
+ back: ControllerAction;
127
+ }>;
128
+ readonly success: Slot<{
129
+ state: AuthenticatedState;
130
+ destination: IdentityDestination | null;
131
+ }>;
132
+ }
133
+ declare function CapxulAuthenticationController({ slots }: {
134
+ readonly slots: AuthenticationSlots;
135
+ }): ReactNode;
136
+ type ProfileSlotProps = {
137
+ readonly intent: "personal";
138
+ readonly state: AuthenticatedState;
139
+ readonly completePersonal: CapxulAuth["completePersonal"];
140
+ readonly cancel: NavigationAction;
141
+ } | {
142
+ readonly intent: "organization";
143
+ readonly state: AuthenticatedState;
144
+ readonly continueOrganization: (profile: ProfileDetails) => void;
145
+ readonly cancel: NavigationAction;
146
+ };
147
+ //#endregion
148
+ //#region src/access/onboarding-controller.d.ts
149
+ interface OnboardingControllerProps {
150
+ readonly intent: "personal" | "organization" | null;
151
+ readonly organizationProfile: ProfileDetails | null;
152
+ readonly submittedOrganization: CreateOrganizationSubmission | null;
153
+ readonly recoveryOptions?: () => InvocationOptions;
154
+ readonly onIntent: (intent: "personal" | "organization") => void;
155
+ readonly onOrganizationProfile: (profile: ProfileDetails | null) => void;
156
+ readonly onSubmittedOrganization: (submission: CreateOrganizationSubmission | null) => void;
157
+ readonly navigation: {
158
+ readonly selectorBack: NavigationAction;
159
+ readonly profileCancel: NavigationAction;
160
+ readonly organizationBack: NavigationAction;
161
+ readonly organizationCancel: NavigationAction;
162
+ };
163
+ readonly slots: {
164
+ readonly intent: Slot<{
165
+ state: AuthenticatedState;
166
+ select: OnboardingControllerProps["onIntent"];
167
+ back: NavigationAction;
168
+ }>;
169
+ readonly profile: Slot<ProfileSlotProps>;
170
+ readonly organization: Slot<{
171
+ state: AuthenticatedState;
172
+ profileDetails: ProfileDetails;
173
+ submitted: CreateOrganizationSubmission | null;
174
+ pinnedHandle: string | null;
175
+ submit: (organization: OrganizationDetails, options: InvocationOptions) => ReturnType<CapxulAuth["createOrganization"]>;
176
+ back: NavigationAction;
177
+ cancel: NavigationAction;
178
+ }>;
179
+ readonly accountProgress: Slot<{
180
+ state: AuthenticatedState;
181
+ account: AccountProgress;
182
+ }>;
183
+ readonly accountFailure: Slot<{
184
+ state: AuthenticatedState;
185
+ account: AccountFailure;
186
+ retry?: RetryAction;
187
+ }>;
188
+ readonly organizationProgress: Slot<{
189
+ state: AuthenticatedState;
190
+ org: OrgProgress;
191
+ }>;
192
+ readonly organizationFailure: Slot<{
193
+ state: AuthenticatedState;
194
+ org: OrgFailure;
195
+ retry?: RetryAction;
196
+ }>;
197
+ readonly ready: Slot<{
198
+ state: AuthenticatedState;
199
+ destination: ReadyDestination;
200
+ }>;
201
+ };
202
+ }
203
+ declare function CapxulOnboardingController(props: OnboardingControllerProps): import("react").ReactNode;
204
+ //#endregion
205
+ export { TransitionListener as A, CreateOrganizationFailure as C, OrganizationDetails as D, InvocationOptions as E, ProfileDetails as O, CapxulSend as S, Destination as T, ReadyDestination as _, ActionResult as a, Slot as b, CapxulAuthenticationController as c, NavigationAction as d, OrgFailure as f, ProfileSlotProps as g, PendingAuthState as h, AccountProgress as i, SendResult as k, ControllerAction as l, OtpPendingState as m, OnboardingControllerProps as n, AuthenticatedState as o, OrgProgress as p, AccountFailure as r, AuthenticationSlots as s, CapxulOnboardingController as t, FaultedState as u, RetryAction as v, CreateOrganizationSubmission as w, CapxulAuth as x, SignedOutState as y };
@@ -0,0 +1,19 @@
1
+ import { n as OnboardingControllerProps, s as AuthenticationSlots } from "../onboarding-controller-DrJiYWfY.mjs";
2
+ import * as React from "react";
3
+ import { ReactNode } from "react";
4
+ import { CapxulTestClient, CapxulTestClock, CapxulTestObservation, CreateCapxulTestClientOptions, SeedTestIdentityInput, createCapxulTestClient } from "@capxul/sdk/testing";
5
+ //#region src/testing/index.d.ts
6
+ export interface CreateCapxulReactTestHarnessOptions extends CreateCapxulTestClientOptions {
7
+ readonly testing?: CapxulTestClient;
8
+ }
9
+ export interface CapxulReactTestHarness {
10
+ readonly testing: CapxulTestClient;
11
+ readonly client: CapxulTestClient["client"];
12
+ readonly provider: (children: ReactNode) => React.JSX.Element;
13
+ readonly authentication: (slots: AuthenticationSlots) => React.JSX.Element;
14
+ readonly onboarding: (props: OnboardingControllerProps) => React.JSX.Element;
15
+ }
16
+ /** Build renderer-neutral React test elements over the real SDK testing client. */
17
+ export declare function createCapxulReactTestHarness(options?: CreateCapxulReactTestHarnessOptions): CapxulReactTestHarness;
18
+ //#endregion
19
+ export { type CapxulTestClient, type CapxulTestClock, type CapxulTestObservation, type CreateCapxulTestClientOptions, type SeedTestIdentityInput, createCapxulTestClient };
@@ -0,0 +1,22 @@
1
+ import { i as CapxulProvider, n as CapxulAuthenticationController, t as CapxulOnboardingController } from "../onboarding-controller-DWuvVuC8.mjs";
2
+ import "react";
3
+ import { jsx } from "react/jsx-runtime";
4
+ import { createCapxulTestClient } from "@capxul/sdk/testing";
5
+ //#region src/testing/index.tsx
6
+ /** Build renderer-neutral React test elements over the real SDK testing client. */
7
+ function createCapxulReactTestHarness(options = {}) {
8
+ const { testing: suppliedTesting, ...clientOptions } = options;
9
+ const testing = suppliedTesting ?? createCapxulTestClient(clientOptions);
10
+ return {
11
+ testing,
12
+ client: testing.client,
13
+ provider: (children) => /* @__PURE__ */ jsx(CapxulProvider, {
14
+ client: testing.client,
15
+ children
16
+ }),
17
+ authentication: (slots) => /* @__PURE__ */ jsx(CapxulAuthenticationController, { slots }),
18
+ onboarding: (props) => /* @__PURE__ */ jsx(CapxulOnboardingController, { ...props })
19
+ };
20
+ }
21
+ //#endregion
22
+ export { createCapxulReactTestHarness, createCapxulTestClient };
package/package.json ADDED
@@ -0,0 +1,94 @@
1
+ {
2
+ "name": "@capxul/sdk-react",
3
+ "version": "0.0.0-rc-2cdddbb91",
4
+ "repository": {
5
+ "type": "git",
6
+ "url": "git+https://github.com/Xelmar-tech/infrastructure.git",
7
+ "directory": "packages/sdk-react"
8
+ },
9
+ "files": [
10
+ "dist",
11
+ "package.json",
12
+ "README.md"
13
+ ],
14
+ "type": "module",
15
+ "imports": {
16
+ "#access": "./src/access/index.ts",
17
+ "#access/client-connection": "./src/access/client-connection.tsx",
18
+ "#access/controllers": "./src/access/controllers.tsx",
19
+ "#access/dashboard-access": "./src/access/dashboard-access.tsx",
20
+ "#access/onboarding-controller": "./src/access/onboarding-controller.tsx",
21
+ "#accounts": "./src/accounts/index.ts",
22
+ "#activity": "./src/activity/index.ts",
23
+ "#activity/activity": "./src/activity/activity.tsx",
24
+ "#media": "./src/media/index.ts",
25
+ "#organizations": "./src/organizations/index.ts",
26
+ "#organizations/org-member": "./src/organizations/org-member.tsx",
27
+ "#package.json": "./package.json",
28
+ "#parties": "./src/parties/index.ts",
29
+ "#parties/contacts": "./src/parties/contacts.tsx",
30
+ "#payments": "./src/payments/index.ts",
31
+ "#payments/send-money": "./src/payments/send-money.tsx",
32
+ "#payroll": "./src/payroll/index.ts",
33
+ "#payroll/payroll": "./src/payroll/payroll.tsx",
34
+ "#payroll/payroll-run": "./src/payroll/payroll-run.tsx",
35
+ "#permissions": "./src/permissions/index.ts",
36
+ "#platform/bootstrap-context": "./src/platform/bootstrap-context.tsx",
37
+ "#platform/client-context": "./src/platform/client-context.tsx",
38
+ "#platform/identity": "./src/platform/identity.tsx",
39
+ "#platform/provider": "./src/platform/provider.tsx",
40
+ "#platform/tests/render-hook-with-capxul": "./src/platform/tests/render-hook-with-capxul.tsx",
41
+ "#profiles": "./src/profiles/index.ts",
42
+ "#testing": "./src/testing/index.tsx",
43
+ "#*": "./src/*.ts"
44
+ },
45
+ "exports": {
46
+ ".": {
47
+ "types": "./dist/index.d.mts",
48
+ "import": "./dist/index.mjs"
49
+ },
50
+ "./testing": {
51
+ "types": "./dist/testing/index.d.mts",
52
+ "import": "./dist/testing/index.mjs"
53
+ }
54
+ },
55
+ "publishConfig": {
56
+ "access": "public"
57
+ },
58
+ "dependencies": {
59
+ "@capxul/sdk": "0.0.0-rc-2cdddbb91"
60
+ },
61
+ "devDependencies": {
62
+ "@tanstack/react-query": "^5.66.9",
63
+ "@testing-library/react": "^16.3.2",
64
+ "@total-typescript/shoehorn": "0.1.2",
65
+ "@types/jsdom": "^28.0.3",
66
+ "@types/react": "^19.2.15",
67
+ "@typescript/native": "npm:typescript@7.0.2",
68
+ "@vitest/coverage-v8": "5.0.1",
69
+ "ink": "^7.0.3",
70
+ "ink-testing-library": "^4.0.0",
71
+ "jsdom": "^29.1.1",
72
+ "react": "^19.2.6",
73
+ "react-dom": "^19.2.6",
74
+ "typescript": "npm:@typescript/typescript6@6.0.2",
75
+ "vite": "npm:@voidzero-dev/vite-plus-core@1.0.0",
76
+ "vite-plus": "1.0.0",
77
+ "vitest": "5.0.1",
78
+ "@capxul/typescript-config": "0.0.0",
79
+ "@capxul/protocol": "0.2.0-beta.5"
80
+ },
81
+ "peerDependencies": {
82
+ "@tanstack/react-query": "^5.66.9",
83
+ "react": "^18.0.0 || ^19.0.0"
84
+ },
85
+ "engines": {
86
+ "node": ">=22.12.0"
87
+ },
88
+ "scripts": {
89
+ "check-types": "vp exec ../../node_modules/@typescript/native/bin/tsc -p tsconfig.json --noEmit",
90
+ "lint": "vp lint -c ../../.oxlintrc.json .",
91
+ "build": "vp pack",
92
+ "_vp-tasks-allowed": "vp-allowed: `test` + `test:coverage` are vp tasks in vite.config.ts so vitest self-writes don't bust cache (#205)."
93
+ }
94
+ }