@syndew/oluso-sdk 0.0.0-stage → 0.1.0
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 +509 -2
- package/dist/auth/embed.global.js +210 -0
- package/dist/auth/embed.global.js.map +1 -0
- package/dist/auth/index.d.mts +535 -0
- package/dist/auth/index.d.ts +535 -0
- package/dist/auth/index.js +2118 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/index.mjs +2088 -0
- package/dist/auth/index.mjs.map +1 -0
- package/dist/embed.global.js +448 -0
- package/dist/embed.global.js.map +1 -0
- package/dist/index.d.mts +810 -0
- package/dist/index.d.ts +810 -0
- package/dist/index.js +2127 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +2095 -0
- package/dist/index.mjs.map +1 -0
- package/dist/react.d.mts +559 -0
- package/dist/react.d.ts +559 -0
- package/dist/react.js +1674 -0
- package/dist/react.js.map +1 -0
- package/dist/react.mjs +1642 -0
- package/dist/react.mjs.map +1 -0
- package/package.json +67 -4
package/dist/react.d.ts
ADDED
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
import React, { ReactNode } from 'react';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* SDK Configuration
|
|
5
|
+
*/
|
|
6
|
+
interface OlusoConfig {
|
|
7
|
+
/**
|
|
8
|
+
* Base URL of the Oluso server
|
|
9
|
+
* @example "https://auth.oluso.io"
|
|
10
|
+
*/
|
|
11
|
+
serverUrl: string;
|
|
12
|
+
/**
|
|
13
|
+
* Tenant identifier (subdomain or ID). Leave it out when the server URL is the tenant's own host, or when your
|
|
14
|
+
* `fetch` already names the tenant.
|
|
15
|
+
* @example "acme" or "tenant_abc123"
|
|
16
|
+
*/
|
|
17
|
+
tenant?: string;
|
|
18
|
+
/**
|
|
19
|
+
* Optional public API key for rate limiting/analytics
|
|
20
|
+
* Not used for authentication - journeys handle their own auth
|
|
21
|
+
*/
|
|
22
|
+
apiKey?: string;
|
|
23
|
+
/**
|
|
24
|
+
* Custom fetch implementation (for SSR or testing)
|
|
25
|
+
*/
|
|
26
|
+
fetch?: typeof fetch;
|
|
27
|
+
/**
|
|
28
|
+
* Extra headers for each request, e.g. the signed-in user's access token (and DPoP proof) for a session your
|
|
29
|
+
* own backend started for that user. Called per request with its method and URL.
|
|
30
|
+
*/
|
|
31
|
+
headers?: (request: {
|
|
32
|
+
method: string;
|
|
33
|
+
url: string;
|
|
34
|
+
}) => Record<string, string> | Promise<Record<string, string>>;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Field definition from a journey policy
|
|
38
|
+
*/
|
|
39
|
+
interface JourneyField {
|
|
40
|
+
name: string;
|
|
41
|
+
type: 'text' | 'email' | 'password' | 'number' | 'date' | 'tel' | 'url' | 'textarea' | 'select' | 'radio' | 'checkbox';
|
|
42
|
+
label: string;
|
|
43
|
+
placeholder?: string;
|
|
44
|
+
description?: string;
|
|
45
|
+
required: boolean;
|
|
46
|
+
options?: Array<{
|
|
47
|
+
value: string;
|
|
48
|
+
label: string;
|
|
49
|
+
}>;
|
|
50
|
+
validation?: {
|
|
51
|
+
minLength?: number;
|
|
52
|
+
maxLength?: number;
|
|
53
|
+
pattern?: string;
|
|
54
|
+
min?: number;
|
|
55
|
+
max?: number;
|
|
56
|
+
};
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Journey metadata returned from the API
|
|
60
|
+
*/
|
|
61
|
+
interface JourneyInfo {
|
|
62
|
+
id: string;
|
|
63
|
+
name: string;
|
|
64
|
+
type: string;
|
|
65
|
+
description?: string;
|
|
66
|
+
fields: JourneyField[];
|
|
67
|
+
ui?: {
|
|
68
|
+
title?: string;
|
|
69
|
+
logoUrl?: string;
|
|
70
|
+
primaryColor?: string;
|
|
71
|
+
backgroundColor?: string;
|
|
72
|
+
};
|
|
73
|
+
requiresAuthentication: boolean;
|
|
74
|
+
}
|
|
75
|
+
/**
|
|
76
|
+
* Submission result
|
|
77
|
+
*/
|
|
78
|
+
interface SubmissionResult {
|
|
79
|
+
success: boolean;
|
|
80
|
+
submissionId?: string;
|
|
81
|
+
message?: string;
|
|
82
|
+
redirectUrl?: string;
|
|
83
|
+
errors?: Record<string, string>;
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* A journey running step by step through the headless API (start, step, session).
|
|
87
|
+
* Every headless call returns the session as it stands after the call.
|
|
88
|
+
*/
|
|
89
|
+
interface JourneySession {
|
|
90
|
+
sessionId: string;
|
|
91
|
+
/** The journey's slug */
|
|
92
|
+
slug: string;
|
|
93
|
+
status: 'in_progress' | 'completed' | 'failed' | 'cancelled' | 'expired';
|
|
94
|
+
success: boolean;
|
|
95
|
+
completed: boolean;
|
|
96
|
+
/** The step waiting for input, while in progress */
|
|
97
|
+
currentStep?: string;
|
|
98
|
+
/** Same as currentStep: set while there is a step to complete */
|
|
99
|
+
nextStep?: string;
|
|
100
|
+
completedSteps: string[];
|
|
101
|
+
expiresAt?: string;
|
|
102
|
+
/** What to render for the current step */
|
|
103
|
+
step?: JourneyStepView;
|
|
104
|
+
/** The step continues elsewhere (e.g. an external identity provider) */
|
|
105
|
+
redirectUrl?: string;
|
|
106
|
+
/** Authentication journeys: the authorization code to redeem with the PKCE verifier */
|
|
107
|
+
code?: string;
|
|
108
|
+
/** Data-collection journeys: the success message once completed */
|
|
109
|
+
message?: string;
|
|
110
|
+
error?: string;
|
|
111
|
+
errorDescription?: string;
|
|
112
|
+
}
|
|
113
|
+
/** A step to render: its definition and the model the server renders it from */
|
|
114
|
+
interface JourneyStepView {
|
|
115
|
+
id: string;
|
|
116
|
+
/** Step type, e.g. local_login, mfa, dynamic_form */
|
|
117
|
+
type: string;
|
|
118
|
+
displayName?: string;
|
|
119
|
+
/** The server view the step renders as */
|
|
120
|
+
view?: string;
|
|
121
|
+
/** Fields, options, messages and errors for the step */
|
|
122
|
+
model?: Record<string, unknown>;
|
|
123
|
+
/** The step as a form any client can draw (see JourneyStepForm) */
|
|
124
|
+
form?: JourneyStepForm;
|
|
125
|
+
/** The hosted view's markup, for a step that has no form description (custom pages, plugin views) */
|
|
126
|
+
html?: string;
|
|
127
|
+
actions: JourneyStepAction[];
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* A step as a form. Posting its fields with the clicked action's name and value is exactly what the hosted page
|
|
131
|
+
* posts, so any journey step can be drawn by any client.
|
|
132
|
+
*/
|
|
133
|
+
interface JourneyStepForm {
|
|
134
|
+
title?: string;
|
|
135
|
+
description?: string;
|
|
136
|
+
/** What went wrong with the last submission */
|
|
137
|
+
error?: string;
|
|
138
|
+
/** Something to tell the person that isn't an error */
|
|
139
|
+
notice?: string;
|
|
140
|
+
fields: JourneyFormField[];
|
|
141
|
+
/** The buttons, in order; each posts the fields with its own name and value */
|
|
142
|
+
actions: JourneyFormAction[];
|
|
143
|
+
links: JourneyFormLink[];
|
|
144
|
+
/** Browser work for the step: passkey, captcha, QR code, recovery codes or waiting */
|
|
145
|
+
widget?: JourneyFormWidget;
|
|
146
|
+
}
|
|
147
|
+
type JourneyFormFieldType = 'text' | 'email' | 'password' | 'number' | 'date' | 'tel' | 'url' | 'textarea' | 'select' | 'radio' | 'checkbox' | 'file' | 'hidden' | 'otp' | 'content';
|
|
148
|
+
interface JourneyFormField {
|
|
149
|
+
name: string;
|
|
150
|
+
type: JourneyFormFieldType | string;
|
|
151
|
+
label?: string;
|
|
152
|
+
placeholder?: string;
|
|
153
|
+
description?: string;
|
|
154
|
+
/** Guidance under the input, e.g. upload limits */
|
|
155
|
+
hint?: string;
|
|
156
|
+
required: boolean;
|
|
157
|
+
readOnly: boolean;
|
|
158
|
+
value?: string;
|
|
159
|
+
error?: string;
|
|
160
|
+
options?: JourneyFormOption[];
|
|
161
|
+
pattern?: string;
|
|
162
|
+
patternError?: string;
|
|
163
|
+
minLength?: number;
|
|
164
|
+
maxLength?: number;
|
|
165
|
+
min?: string;
|
|
166
|
+
max?: string;
|
|
167
|
+
rows?: number;
|
|
168
|
+
autocomplete?: string;
|
|
169
|
+
autofocus: boolean;
|
|
170
|
+
accept?: string;
|
|
171
|
+
maxFiles?: number;
|
|
172
|
+
maxFileSizeMb?: number;
|
|
173
|
+
capture?: string;
|
|
174
|
+
/** Phone: countries to pick from; the country is posted as `${name}__country` */
|
|
175
|
+
countries?: JourneyFormCountry[];
|
|
176
|
+
country?: string;
|
|
177
|
+
showWhen?: JourneyFormCondition;
|
|
178
|
+
/** Shown only while every one of these is met too */
|
|
179
|
+
showWhenAll?: JourneyFormCondition[];
|
|
180
|
+
group?: string;
|
|
181
|
+
}
|
|
182
|
+
interface JourneyFormOption {
|
|
183
|
+
value: string;
|
|
184
|
+
label: string;
|
|
185
|
+
description?: string;
|
|
186
|
+
disabled: boolean;
|
|
187
|
+
}
|
|
188
|
+
interface JourneyFormCountry {
|
|
189
|
+
code: string;
|
|
190
|
+
name: string;
|
|
191
|
+
dialCode: string;
|
|
192
|
+
flag?: string;
|
|
193
|
+
}
|
|
194
|
+
interface JourneyFormCondition {
|
|
195
|
+
field: string;
|
|
196
|
+
operator: string;
|
|
197
|
+
value?: string;
|
|
198
|
+
}
|
|
199
|
+
interface JourneyFormAction {
|
|
200
|
+
/** The posted name; absent for a button that posts no name of its own */
|
|
201
|
+
name?: string;
|
|
202
|
+
value?: string;
|
|
203
|
+
label: string;
|
|
204
|
+
/** Text shown with the button, e.g. "Didn't get the code?" before a resend link */
|
|
205
|
+
description?: string;
|
|
206
|
+
/** A question to confirm before the button posts; the renderer asks inline */
|
|
207
|
+
confirm?: string;
|
|
208
|
+
/** More values the button posts */
|
|
209
|
+
values?: Record<string, string>;
|
|
210
|
+
/** False: the button posts only its own name, value and values, none of the step's fields */
|
|
211
|
+
postsFields: boolean;
|
|
212
|
+
kind: 'primary' | 'secondary' | 'link' | 'cancel' | string;
|
|
213
|
+
skipValidation: boolean;
|
|
214
|
+
}
|
|
215
|
+
interface JourneyFormLink {
|
|
216
|
+
label: string;
|
|
217
|
+
url: string;
|
|
218
|
+
}
|
|
219
|
+
interface JourneyFormWidget {
|
|
220
|
+
type: 'webauthn_get' | 'webauthn_create' | 'captcha' | 'qr' | 'codes' | 'poll' | string;
|
|
221
|
+
data?: Record<string, unknown>;
|
|
222
|
+
/** Where the widget's result is posted */
|
|
223
|
+
resultField?: string;
|
|
224
|
+
/** The action posted with the result */
|
|
225
|
+
submit?: JourneyFormAction;
|
|
226
|
+
}
|
|
227
|
+
interface JourneyStepAction {
|
|
228
|
+
id: string;
|
|
229
|
+
label: string;
|
|
230
|
+
isPrimary: boolean;
|
|
231
|
+
isCancel: boolean;
|
|
232
|
+
}
|
|
233
|
+
/** The session after a step was submitted */
|
|
234
|
+
type StepResult = JourneySession;
|
|
235
|
+
/**
|
|
236
|
+
* Event types emitted by the SDK
|
|
237
|
+
*/
|
|
238
|
+
type OlusoEventType = 'journey:started' | 'journey:step' | 'journey:completed' | 'journey:error' | 'submission:success' | 'submission:error' | 'auth:success' | 'auth:error';
|
|
239
|
+
interface OlusoEvent {
|
|
240
|
+
type: OlusoEventType;
|
|
241
|
+
/** The journey's slug */
|
|
242
|
+
slug: string;
|
|
243
|
+
/** The headless session, for journey events */
|
|
244
|
+
sessionId?: string;
|
|
245
|
+
data?: unknown;
|
|
246
|
+
error?: Error;
|
|
247
|
+
}
|
|
248
|
+
type OlusoEventListener = (event: OlusoEvent) => void;
|
|
249
|
+
|
|
250
|
+
/**
|
|
251
|
+
* Oluso SDK Client
|
|
252
|
+
*
|
|
253
|
+
* @example
|
|
254
|
+
* ```typescript
|
|
255
|
+
* const oluso = new OlusoClient({
|
|
256
|
+
* serverUrl: 'https://auth.oluso.io',
|
|
257
|
+
* tenant: 'acme',
|
|
258
|
+
* });
|
|
259
|
+
*
|
|
260
|
+
* // Get journey info (form fields, etc.)
|
|
261
|
+
* const journey = await oluso.getJourney('waitlist');
|
|
262
|
+
*
|
|
263
|
+
* // Submit data
|
|
264
|
+
* const result = await oluso.submit('waitlist', {
|
|
265
|
+
* email: 'user@example.com',
|
|
266
|
+
* name: 'John Doe',
|
|
267
|
+
* });
|
|
268
|
+
* ```
|
|
269
|
+
*/
|
|
270
|
+
declare class OlusoClient {
|
|
271
|
+
private config;
|
|
272
|
+
private fetchFn;
|
|
273
|
+
private listeners;
|
|
274
|
+
constructor(config: OlusoConfig);
|
|
275
|
+
/**
|
|
276
|
+
* Get journey information including form fields. Journeys are named by slug.
|
|
277
|
+
*/
|
|
278
|
+
getJourney(slug: string): Promise<JourneyInfo>;
|
|
279
|
+
/**
|
|
280
|
+
* Submit data to a data collection journey (waitlist, contact, survey, etc.)
|
|
281
|
+
*/
|
|
282
|
+
submit(slug: string, data: Record<string, unknown>, options?: {
|
|
283
|
+
/** Client-side metadata */
|
|
284
|
+
metadata?: Record<string, string>;
|
|
285
|
+
/** Honeypot field for spam detection */
|
|
286
|
+
honeypot?: string;
|
|
287
|
+
}): Promise<SubmissionResult>;
|
|
288
|
+
/**
|
|
289
|
+
* Start a multi-step journey and run its first step. Without data the session's `step`
|
|
290
|
+
* is the first step to render; with data, that is the first step's input.
|
|
291
|
+
*/
|
|
292
|
+
startJourney(slug: string, data?: Record<string, unknown>): Promise<JourneySession>;
|
|
293
|
+
/**
|
|
294
|
+
* Start a sign-in (or any authentication) journey for a public client. When the session completes it carries an
|
|
295
|
+
* authorization code, redeemed at the token endpoint with the PKCE verifier and redirect_uri "postmessage". Use
|
|
296
|
+
* this when your app keeps its own tokens; OlusoAuth.mountSignIn does the whole round trip for you.
|
|
297
|
+
*/
|
|
298
|
+
startAuthJourney(slug: string, auth: {
|
|
299
|
+
clientId: string;
|
|
300
|
+
codeChallenge: string;
|
|
301
|
+
scope?: string;
|
|
302
|
+
}, data?: Record<string, unknown>): Promise<JourneySession>;
|
|
303
|
+
/**
|
|
304
|
+
* Submit input (or an action such as "resend") for the session's current step.
|
|
305
|
+
* The result is the session afterwards: the next step to render, or the completion.
|
|
306
|
+
*/
|
|
307
|
+
submitStep(sessionId: string, data?: Record<string, unknown>, action?: string): Promise<StepResult>;
|
|
308
|
+
/**
|
|
309
|
+
* Submit the current step the way a form posts it: every field, files under their field's name, and the
|
|
310
|
+
* clicked button's name and value. Use this for steps with file fields; `action` is a step action such as "init".
|
|
311
|
+
*/
|
|
312
|
+
submitStepForm(sessionId: string, form: FormData, action?: string): Promise<StepResult>;
|
|
313
|
+
/** The server this client talks to */
|
|
314
|
+
get serverUrl(): string;
|
|
315
|
+
/**
|
|
316
|
+
* Get where a multi-step session stands (status, current step), without running it
|
|
317
|
+
*/
|
|
318
|
+
getSession(sessionId: string): Promise<JourneySession>;
|
|
319
|
+
/**
|
|
320
|
+
* URL of the hosted journey page (/journey/start/{slug}) to redirect to
|
|
321
|
+
*/
|
|
322
|
+
getJourneyUrl(slug: string, options?: {
|
|
323
|
+
redirectUri?: string;
|
|
324
|
+
state?: string;
|
|
325
|
+
}): string;
|
|
326
|
+
/**
|
|
327
|
+
* URL of the hosted journey page (/journey/start/{slug}) for an iframe
|
|
328
|
+
*/
|
|
329
|
+
getEmbedUrl(slug: string, options?: {
|
|
330
|
+
theme?: 'light' | 'dark';
|
|
331
|
+
hideHeader?: boolean;
|
|
332
|
+
}): string;
|
|
333
|
+
/**
|
|
334
|
+
* Subscribe to SDK events
|
|
335
|
+
*/
|
|
336
|
+
on(event: OlusoEventType | '*', listener: OlusoEventListener): () => void;
|
|
337
|
+
/**
|
|
338
|
+
* Unsubscribe from SDK events
|
|
339
|
+
*/
|
|
340
|
+
off(event: OlusoEventType | '*', listener: OlusoEventListener): void;
|
|
341
|
+
private emit;
|
|
342
|
+
private request;
|
|
343
|
+
}
|
|
344
|
+
/**
|
|
345
|
+
* Custom error class for SDK errors
|
|
346
|
+
*/
|
|
347
|
+
declare class OlusoError extends Error {
|
|
348
|
+
readonly status: number;
|
|
349
|
+
readonly code?: string | undefined;
|
|
350
|
+
readonly fieldErrors?: Record<string, string> | undefined;
|
|
351
|
+
constructor(message: string, status: number, code?: string | undefined, fieldErrors?: Record<string, string> | undefined);
|
|
352
|
+
}
|
|
353
|
+
|
|
354
|
+
/** Text the renderer shows itself; everything about a step comes from the server in the person's language. */
|
|
355
|
+
interface JourneyLabels {
|
|
356
|
+
loading: string;
|
|
357
|
+
completed: string;
|
|
358
|
+
failed: string;
|
|
359
|
+
expired: string;
|
|
360
|
+
restart: string;
|
|
361
|
+
takePhoto: string;
|
|
362
|
+
copy: string;
|
|
363
|
+
copied: string;
|
|
364
|
+
passkey: string;
|
|
365
|
+
retry: string;
|
|
366
|
+
waiting: string;
|
|
367
|
+
unavailable: string;
|
|
368
|
+
}
|
|
369
|
+
|
|
370
|
+
interface OlusoProviderProps {
|
|
371
|
+
config: OlusoConfig;
|
|
372
|
+
children: ReactNode;
|
|
373
|
+
}
|
|
374
|
+
/**
|
|
375
|
+
* Provider component for Oluso SDK
|
|
376
|
+
*
|
|
377
|
+
* @example
|
|
378
|
+
* ```tsx
|
|
379
|
+
* <OlusoProvider config={{ serverUrl: 'https://auth.yoursite.com', tenant: 'acme' }}>
|
|
380
|
+
* <App />
|
|
381
|
+
* </OlusoProvider>
|
|
382
|
+
* ```
|
|
383
|
+
*/
|
|
384
|
+
declare function OlusoProvider({ config, children }: OlusoProviderProps): React.JSX.Element;
|
|
385
|
+
/**
|
|
386
|
+
* Hook to access the Oluso client
|
|
387
|
+
*/
|
|
388
|
+
declare function useOluso(): OlusoClient;
|
|
389
|
+
interface UseJourneyOptions {
|
|
390
|
+
/** The journey's slug (as in /journey/start/{slug}) */
|
|
391
|
+
slug: string;
|
|
392
|
+
/** Callback on successful submission */
|
|
393
|
+
onSuccess?: (result: SubmissionResult) => void;
|
|
394
|
+
/** Callback on error */
|
|
395
|
+
onError?: (error: OlusoError) => void;
|
|
396
|
+
/** Initial form values */
|
|
397
|
+
defaultValues?: Record<string, unknown>;
|
|
398
|
+
}
|
|
399
|
+
interface UseJourneyResult {
|
|
400
|
+
/** Journey metadata and field definitions */
|
|
401
|
+
journey: JourneyInfo | null;
|
|
402
|
+
/** Loading state for initial fetch */
|
|
403
|
+
isLoading: boolean;
|
|
404
|
+
/** Submitting state */
|
|
405
|
+
isSubmitting: boolean;
|
|
406
|
+
/** Error from fetch or submission */
|
|
407
|
+
error: OlusoError | null;
|
|
408
|
+
/** Current form values */
|
|
409
|
+
values: Record<string, unknown>;
|
|
410
|
+
/** Field-level errors */
|
|
411
|
+
fieldErrors: Record<string, string>;
|
|
412
|
+
/** Update a field value */
|
|
413
|
+
setValue: (field: string, value: unknown) => void;
|
|
414
|
+
/** Submit the form */
|
|
415
|
+
submit: () => Promise<SubmissionResult | null>;
|
|
416
|
+
/** Reset the form */
|
|
417
|
+
reset: () => void;
|
|
418
|
+
}
|
|
419
|
+
/**
|
|
420
|
+
* Hook for working with a journey (headless)
|
|
421
|
+
*
|
|
422
|
+
* @example
|
|
423
|
+
* ```tsx
|
|
424
|
+
* function WaitlistForm() {
|
|
425
|
+
* const { journey, values, setValue, submit, isSubmitting, fieldErrors } = useJourney({
|
|
426
|
+
* slug: 'waitlist',
|
|
427
|
+
* onSuccess: () => alert('Thanks for signing up!'),
|
|
428
|
+
* });
|
|
429
|
+
*
|
|
430
|
+
* if (!journey) return <div>Loading...</div>;
|
|
431
|
+
*
|
|
432
|
+
* return (
|
|
433
|
+
* <form onSubmit={(e) => { e.preventDefault(); submit(); }}>
|
|
434
|
+
* {journey.fields.map((field) => (
|
|
435
|
+
* <div key={field.name}>
|
|
436
|
+
* <label>{field.label}</label>
|
|
437
|
+
* <input
|
|
438
|
+
* type={field.type}
|
|
439
|
+
* value={values[field.name] as string || ''}
|
|
440
|
+
* onChange={(e) => setValue(field.name, e.target.value)}
|
|
441
|
+
* />
|
|
442
|
+
* {fieldErrors[field.name] && <span>{fieldErrors[field.name]}</span>}
|
|
443
|
+
* </div>
|
|
444
|
+
* ))}
|
|
445
|
+
* <button type="submit" disabled={isSubmitting}>
|
|
446
|
+
* {isSubmitting ? 'Submitting...' : 'Submit'}
|
|
447
|
+
* </button>
|
|
448
|
+
* </form>
|
|
449
|
+
* );
|
|
450
|
+
* }
|
|
451
|
+
* ```
|
|
452
|
+
*/
|
|
453
|
+
declare function useJourney(options: UseJourneyOptions): UseJourneyResult;
|
|
454
|
+
interface JourneyFormProps {
|
|
455
|
+
/** The journey's slug (as in /journey/start/{slug}) */
|
|
456
|
+
slug: string;
|
|
457
|
+
/** Callback on successful submission */
|
|
458
|
+
onSuccess?: (result: SubmissionResult) => void;
|
|
459
|
+
/** Callback on error */
|
|
460
|
+
onError?: (error: OlusoError) => void;
|
|
461
|
+
/** Custom class name */
|
|
462
|
+
className?: string;
|
|
463
|
+
/** Custom submit button text */
|
|
464
|
+
submitText?: string;
|
|
465
|
+
/** Custom loading text */
|
|
466
|
+
loadingText?: string;
|
|
467
|
+
/** Render custom field */
|
|
468
|
+
renderField?: (field: JourneyField, props: FieldRenderProps) => ReactNode;
|
|
469
|
+
/** Render custom submit button */
|
|
470
|
+
renderSubmit?: (props: {
|
|
471
|
+
isSubmitting: boolean;
|
|
472
|
+
onClick: () => void;
|
|
473
|
+
}) => ReactNode;
|
|
474
|
+
/** Show success message instead of form after submission */
|
|
475
|
+
showSuccessMessage?: boolean;
|
|
476
|
+
/** Custom success message component */
|
|
477
|
+
renderSuccess?: (result: SubmissionResult) => ReactNode;
|
|
478
|
+
}
|
|
479
|
+
interface FieldRenderProps {
|
|
480
|
+
value: unknown;
|
|
481
|
+
onChange: (value: unknown) => void;
|
|
482
|
+
error?: string;
|
|
483
|
+
}
|
|
484
|
+
/**
|
|
485
|
+
* Pre-built form component that renders a journey form
|
|
486
|
+
*
|
|
487
|
+
* @example
|
|
488
|
+
* ```tsx
|
|
489
|
+
* <JourneyForm
|
|
490
|
+
* slug="waitlist"
|
|
491
|
+
* onSuccess={() => console.log('Submitted!')}
|
|
492
|
+
* submitText="Join Waitlist"
|
|
493
|
+
* />
|
|
494
|
+
* ```
|
|
495
|
+
*/
|
|
496
|
+
declare function JourneyForm({ slug, onSuccess, onError, className, submitText, loadingText, renderField, renderSubmit, showSuccessMessage, renderSuccess, }: JourneyFormProps): React.JSX.Element;
|
|
497
|
+
interface JourneyProps {
|
|
498
|
+
/** Start this journey by slug (a waitlist, a contact form, a survey, a sign-up) */
|
|
499
|
+
slug?: string;
|
|
500
|
+
/** Input for the first step */
|
|
501
|
+
data?: Record<string, unknown>;
|
|
502
|
+
/** Continue a session your backend started, e.g. for the signed-in user */
|
|
503
|
+
session?: JourneySession;
|
|
504
|
+
/** Start the session yourself, e.g. a sign-in journey with PKCE */
|
|
505
|
+
start?: () => Promise<JourneySession>;
|
|
506
|
+
onStep?: (session: JourneySession) => void;
|
|
507
|
+
onComplete?: (session: JourneySession) => void | Promise<void>;
|
|
508
|
+
onError?: (error: Error, session?: JourneySession) => void;
|
|
509
|
+
onRedirect?: (url: string, session: JourneySession) => void;
|
|
510
|
+
showCompletion?: boolean;
|
|
511
|
+
theme?: 'light' | 'dark' | 'auto';
|
|
512
|
+
unstyled?: boolean;
|
|
513
|
+
labels?: Partial<JourneyLabels>;
|
|
514
|
+
className?: string;
|
|
515
|
+
style?: React.CSSProperties;
|
|
516
|
+
}
|
|
517
|
+
/**
|
|
518
|
+
* Render any journey in place and run it step by step: forms with uploads, sign-in with MFA or passkeys,
|
|
519
|
+
* verification codes, consent. Uses the client from OlusoProvider.
|
|
520
|
+
*
|
|
521
|
+
* @example
|
|
522
|
+
* ```tsx
|
|
523
|
+
* <Journey slug="contact-us" onComplete={() => setSent(true)} />
|
|
524
|
+
* ```
|
|
525
|
+
*/
|
|
526
|
+
declare function Journey({ className, style, ...options }: JourneyProps): React.JSX.Element;
|
|
527
|
+
interface JourneyEmbedProps {
|
|
528
|
+
/** The journey's slug (as in /journey/start/{slug}) */
|
|
529
|
+
slug: string;
|
|
530
|
+
/** Width of the iframe */
|
|
531
|
+
width?: string | number;
|
|
532
|
+
/** Height of the iframe */
|
|
533
|
+
height?: string | number;
|
|
534
|
+
/** Theme */
|
|
535
|
+
theme?: 'light' | 'dark';
|
|
536
|
+
/** Hide the header */
|
|
537
|
+
hideHeader?: boolean;
|
|
538
|
+
/** Custom class name */
|
|
539
|
+
className?: string;
|
|
540
|
+
/** Custom style */
|
|
541
|
+
style?: React.CSSProperties;
|
|
542
|
+
/** Callback when journey completes (via postMessage) */
|
|
543
|
+
onComplete?: (result: SubmissionResult) => void;
|
|
544
|
+
}
|
|
545
|
+
/**
|
|
546
|
+
* Embed a journey via iframe
|
|
547
|
+
*
|
|
548
|
+
* @example
|
|
549
|
+
* ```tsx
|
|
550
|
+
* <JourneyEmbed
|
|
551
|
+
* slug="waitlist"
|
|
552
|
+
* height={400}
|
|
553
|
+
* onComplete={(result) => console.log('Submitted!', result)}
|
|
554
|
+
* />
|
|
555
|
+
* ```
|
|
556
|
+
*/
|
|
557
|
+
declare function JourneyEmbed({ slug, width, height, theme, hideHeader, className, style, onComplete, }: JourneyEmbedProps): React.JSX.Element;
|
|
558
|
+
|
|
559
|
+
export { type FieldRenderProps, Journey, JourneyEmbed, type JourneyEmbedProps, JourneyForm, type JourneyFormProps, type JourneyProps, OlusoProvider, type OlusoProviderProps, type UseJourneyOptions, type UseJourneyResult, useJourney, useOluso };
|