@incodetech/core 2.0.0-alpha.1 → 2.0.0-alpha.3

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.
Files changed (104) hide show
  1. package/dist/Manager-6BwbaI_H.d.ts +19 -0
  2. package/dist/StateMachine-7c1gcu94.d.ts +2 -0
  3. package/dist/addEvent-1Mi5CEiq.esm.js +16 -0
  4. package/dist/chunk-C_Yo44FK.esm.js +49 -0
  5. package/dist/email.d.ts +264 -0
  6. package/dist/email.esm.js +479 -0
  7. package/dist/endpoints-D_pUMaqA.esm.js +1701 -0
  8. package/dist/flow.d.ts +578 -0
  9. package/dist/flow.esm.js +628 -0
  10. package/dist/index.d.ts +226 -0
  11. package/dist/index.esm.js +155 -0
  12. package/dist/lib-CyIAFRfr.esm.js +12499 -0
  13. package/dist/permissionServices-CVR0Pq38.esm.js +72 -0
  14. package/dist/phone.d.ts +292 -0
  15. package/dist/phone.esm.js +550 -0
  16. package/dist/selfie.d.ts +758 -0
  17. package/dist/selfie.esm.js +978 -0
  18. package/dist/types-tq1ypYSL.d.ts +5 -0
  19. package/dist/warmup-Dr7OcFND.d.ts +55 -0
  20. package/dist/xstate.esm-B_rda9yU.esm.js +3261 -0
  21. package/package.json +14 -11
  22. package/src/camera/cameraActor.ts +0 -21
  23. package/src/camera/cameraService.test.ts +0 -437
  24. package/src/camera/cameraService.ts +0 -165
  25. package/src/camera/cameraServices.test.ts +0 -66
  26. package/src/camera/cameraServices.ts +0 -26
  27. package/src/camera/cameraStateMachine.test.ts +0 -602
  28. package/src/camera/cameraStateMachine.ts +0 -264
  29. package/src/camera/index.ts +0 -5
  30. package/src/camera/types.ts +0 -17
  31. package/src/device/getBrowser.ts +0 -31
  32. package/src/device/getDeviceClass.ts +0 -29
  33. package/src/device/index.ts +0 -2
  34. package/src/email/__mocks__/emailMocks.ts +0 -59
  35. package/src/email/emailActor.ts +0 -15
  36. package/src/email/emailManager.test.ts +0 -573
  37. package/src/email/emailManager.ts +0 -427
  38. package/src/email/emailServices.ts +0 -66
  39. package/src/email/emailStateMachine.test.ts +0 -741
  40. package/src/email/emailStateMachine.ts +0 -367
  41. package/src/email/index.ts +0 -39
  42. package/src/email/types.ts +0 -60
  43. package/src/events/addEvent.ts +0 -20
  44. package/src/events/types.ts +0 -7
  45. package/src/flow/__mocks__/flowMocks.ts +0 -84
  46. package/src/flow/flowActor.ts +0 -13
  47. package/src/flow/flowAnalyzer.test.ts +0 -266
  48. package/src/flow/flowAnalyzer.ts +0 -37
  49. package/src/flow/flowCompletionService.ts +0 -21
  50. package/src/flow/flowManager.test.ts +0 -560
  51. package/src/flow/flowManager.ts +0 -235
  52. package/src/flow/flowServices.test.ts +0 -109
  53. package/src/flow/flowServices.ts +0 -13
  54. package/src/flow/flowStateMachine.test.ts +0 -334
  55. package/src/flow/flowStateMachine.ts +0 -182
  56. package/src/flow/index.ts +0 -21
  57. package/src/flow/moduleLoader.test.ts +0 -136
  58. package/src/flow/moduleLoader.ts +0 -73
  59. package/src/flow/orchestratedFlowManager.test.ts +0 -240
  60. package/src/flow/orchestratedFlowManager.ts +0 -231
  61. package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
  62. package/src/flow/orchestratedFlowStateMachine.ts +0 -325
  63. package/src/flow/types.ts +0 -434
  64. package/src/http/__mocks__/api.ts +0 -88
  65. package/src/http/api.test.ts +0 -231
  66. package/src/http/api.ts +0 -90
  67. package/src/http/endpoints.ts +0 -17
  68. package/src/index.ts +0 -33
  69. package/src/permissions/index.ts +0 -2
  70. package/src/permissions/permissionServices.ts +0 -31
  71. package/src/permissions/types.ts +0 -3
  72. package/src/phone/__mocks__/phoneMocks.ts +0 -71
  73. package/src/phone/index.ts +0 -39
  74. package/src/phone/phoneActor.ts +0 -15
  75. package/src/phone/phoneManager.test.ts +0 -393
  76. package/src/phone/phoneManager.ts +0 -458
  77. package/src/phone/phoneServices.ts +0 -98
  78. package/src/phone/phoneStateMachine.test.ts +0 -918
  79. package/src/phone/phoneStateMachine.ts +0 -422
  80. package/src/phone/types.ts +0 -83
  81. package/src/recordings/recordingsRepository.test.ts +0 -87
  82. package/src/recordings/recordingsRepository.ts +0 -48
  83. package/src/recordings/streamingEvents.ts +0 -10
  84. package/src/selfie/__mocks__/selfieMocks.ts +0 -26
  85. package/src/selfie/index.ts +0 -14
  86. package/src/selfie/selfieActor.ts +0 -17
  87. package/src/selfie/selfieErrorUtils.test.ts +0 -116
  88. package/src/selfie/selfieErrorUtils.ts +0 -66
  89. package/src/selfie/selfieManager.test.ts +0 -297
  90. package/src/selfie/selfieManager.ts +0 -301
  91. package/src/selfie/selfieServices.ts +0 -362
  92. package/src/selfie/selfieStateMachine.test.ts +0 -283
  93. package/src/selfie/selfieStateMachine.ts +0 -804
  94. package/src/selfie/selfieUploadService.test.ts +0 -90
  95. package/src/selfie/selfieUploadService.ts +0 -81
  96. package/src/selfie/types.ts +0 -103
  97. package/src/session/index.ts +0 -5
  98. package/src/session/sessionService.ts +0 -78
  99. package/src/setup.test.ts +0 -61
  100. package/src/setup.ts +0 -171
  101. package/tsconfig.json +0 -13
  102. package/tsdown.config.ts +0 -22
  103. package/vitest.config.ts +0 -37
  104. package/vitest.setup.ts +0 -135
@@ -0,0 +1,479 @@
1
+ import { g as createManager, n as api, t as endpoints } from "./endpoints-D_pUMaqA.esm.js";
2
+ import { a as createActor, i as fromPromise, n as assign, r as fromCallback, t as setup } from "./xstate.esm-B_rda9yU.esm.js";
3
+ import { t as addEvent } from "./addEvent-1Mi5CEiq.esm.js";
4
+
5
+ //#region src/email/emailServices.ts
6
+ async function fetchEmail(signal) {
7
+ const res = await api.get(endpoints.getEmail, { signal });
8
+ if (!res.ok) throw new Error(`GET ${endpoints.getEmail} failed: ${res.status} ${res.statusText}`);
9
+ return res.data;
10
+ }
11
+ async function addEmail(params, signal) {
12
+ const res = await api.post(endpoints.email, { email: params.email }, { signal });
13
+ if (!res.ok) throw new Error(`POST ${endpoints.email} failed: ${res.status} ${res.statusText}`);
14
+ return res.data;
15
+ }
16
+ async function sendEmailOtp(signal) {
17
+ const res = await api.get(`${endpoints.sendSmsOtp}?communicationchannel=EMAIL`, { signal });
18
+ if (!res.ok) throw new Error(`GET ${endpoints.sendSmsOtp} failed: ${res.status} ${res.statusText}`);
19
+ }
20
+ async function verifyEmailOtp(code, signal) {
21
+ const res = await api.get(`${endpoints.compareOtp}?code=${code}&channel=EMAIL`, { signal });
22
+ if (!res.ok) throw new Error(`GET ${endpoints.compareOtp} failed: ${res.status} ${res.statusText}`);
23
+ return res.data;
24
+ }
25
+
26
+ //#endregion
27
+ //#region src/email/emailStateMachine.ts
28
+ const RESEND_TIMER_SECONDS = 30;
29
+ const emailMachine = setup({
30
+ types: {
31
+ context: {},
32
+ events: {},
33
+ input: {}
34
+ },
35
+ actors: {
36
+ fetchEmail: fromPromise(async ({ signal }) => {
37
+ return fetchEmail(signal);
38
+ }),
39
+ submitEmail: fromPromise(async ({ input, signal }) => {
40
+ return addEmail({ email: input.email }, signal);
41
+ }),
42
+ sendOtp: fromPromise(async ({ signal }) => {
43
+ return sendEmailOtp(signal);
44
+ }),
45
+ verifyOtp: fromPromise(async ({ input, signal }) => {
46
+ return verifyEmailOtp(input.code, signal);
47
+ }),
48
+ resendTimer: fromCallback(({ sendBack }) => {
49
+ let seconds = RESEND_TIMER_SECONDS;
50
+ const interval = setInterval(() => {
51
+ seconds -= 1;
52
+ sendBack({ type: "TICK" });
53
+ if (seconds <= 0) clearInterval(interval);
54
+ }, 1e3);
55
+ return () => clearInterval(interval);
56
+ })
57
+ },
58
+ actions: {
59
+ setPrefilledEmail: assign(({ event }) => {
60
+ const email = event.output.email;
61
+ return {
62
+ prefilledEmail: email,
63
+ email
64
+ };
65
+ }),
66
+ setEmail: assign(({ event }) => {
67
+ const e = event;
68
+ return {
69
+ email: e.email,
70
+ isValid: e.isValid,
71
+ emailError: e.isValid ? void 0 : "Invalid email address"
72
+ };
73
+ }),
74
+ setEmailError: assign(({ event }) => ({ emailError: String(event.error) })),
75
+ setError: assign(({ event }) => ({ error: String(event.error) })),
76
+ clearError: assign({ error: () => void 0 }),
77
+ clearEmailError: assign({ emailError: () => void 0 }),
78
+ setOtpCode: assign(({ event }) => ({
79
+ otpCode: event.code,
80
+ otpError: void 0
81
+ })),
82
+ setOtpError: assign(({ context, event }) => ({
83
+ otpError: String(event.error),
84
+ attemptsRemaining: context.attemptsRemaining - 1
85
+ })),
86
+ clearOtpError: assign({
87
+ otpError: () => void 0,
88
+ otpCode: () => ""
89
+ }),
90
+ startResendTimer: assign({
91
+ resendTimer: () => RESEND_TIMER_SECONDS,
92
+ resendTimerActive: () => true
93
+ }),
94
+ tickResendTimer: assign(({ context }) => {
95
+ const newTimer = Math.max(0, context.resendTimer - 1);
96
+ return {
97
+ resendTimer: newTimer,
98
+ resendTimerActive: newTimer > 0
99
+ };
100
+ }),
101
+ stopResendTimer: assign({ resendTimerActive: () => false }),
102
+ resetContext: assign(({ context }) => ({
103
+ config: context.config,
104
+ email: "",
105
+ isValid: false,
106
+ emailError: void 0,
107
+ prefilledEmail: void 0,
108
+ error: void 0,
109
+ otpCode: "",
110
+ otpError: void 0,
111
+ attemptsRemaining: context.config.maxOtpAttempts ?? 3,
112
+ resendTimer: 0,
113
+ resendTimerActive: false
114
+ })),
115
+ sendEmailSubmitEvent: () => {
116
+ addEvent({
117
+ code: "continue",
118
+ module: "email",
119
+ screen: "emailInput"
120
+ });
121
+ }
122
+ },
123
+ guards: {
124
+ hasPrefill: ({ context }) => context.config.prefill,
125
+ hasOtpVerification: ({ context }) => context.config.otpVerification,
126
+ isValidEmail: ({ context }) => context.isValid,
127
+ hasAttemptsRemaining: ({ context }) => context.attemptsRemaining > 0,
128
+ canResend: ({ context }) => !context.resendTimerActive
129
+ }
130
+ }).createMachine({
131
+ id: "email",
132
+ initial: "idle",
133
+ context: ({ input }) => ({
134
+ config: input.config,
135
+ email: "",
136
+ isValid: false,
137
+ emailError: void 0,
138
+ prefilledEmail: void 0,
139
+ error: void 0,
140
+ otpCode: "",
141
+ otpError: void 0,
142
+ attemptsRemaining: input.config.maxOtpAttempts ?? 3,
143
+ resendTimer: 0,
144
+ resendTimerActive: false
145
+ }),
146
+ states: {
147
+ idle: { on: { LOAD: [{
148
+ target: "loadingPrefill",
149
+ guard: "hasPrefill"
150
+ }, { target: "inputting" }] } },
151
+ loadingPrefill: { invoke: {
152
+ id: "fetchEmail",
153
+ src: "fetchEmail",
154
+ onDone: {
155
+ target: "inputting",
156
+ actions: "setPrefilledEmail"
157
+ },
158
+ onError: { target: "inputting" }
159
+ } },
160
+ inputting: {
161
+ entry: "clearEmailError",
162
+ on: {
163
+ EMAIL_CHANGED: { actions: "setEmail" },
164
+ SUBMIT: {
165
+ target: "submitting",
166
+ guard: "isValidEmail"
167
+ }
168
+ }
169
+ },
170
+ submitting: { invoke: {
171
+ id: "submitEmail",
172
+ src: "submitEmail",
173
+ input: ({ context }) => ({ email: context.email }),
174
+ onDone: [{
175
+ target: "sendingOtp",
176
+ guard: "hasOtpVerification",
177
+ actions: "sendEmailSubmitEvent"
178
+ }, {
179
+ target: "success",
180
+ actions: "sendEmailSubmitEvent"
181
+ }],
182
+ onError: {
183
+ target: "inputting",
184
+ actions: "setEmailError"
185
+ }
186
+ } },
187
+ sendingOtp: { invoke: {
188
+ id: "sendOtp",
189
+ src: "sendOtp",
190
+ onDone: { target: "awaitingOtp" },
191
+ onError: {
192
+ target: "awaitingOtp",
193
+ actions: "setError"
194
+ }
195
+ } },
196
+ awaitingOtp: {
197
+ entry: "startResendTimer",
198
+ invoke: {
199
+ id: "resendTimer",
200
+ src: "resendTimer"
201
+ },
202
+ on: {
203
+ TICK: { actions: "tickResendTimer" },
204
+ OTP_CHANGED: { actions: "setOtpCode" },
205
+ VERIFY_OTP: { target: "verifyingOtp" },
206
+ RESEND_OTP: {
207
+ target: "sendingOtp",
208
+ guard: "canResend"
209
+ },
210
+ BACK: { target: "inputting" }
211
+ }
212
+ },
213
+ verifyingOtp: { invoke: {
214
+ id: "verifyOtp",
215
+ src: "verifyOtp",
216
+ input: ({ context }) => ({ code: context.otpCode }),
217
+ onDone: [
218
+ {
219
+ target: "success",
220
+ guard: ({ event }) => event.output.success === true
221
+ },
222
+ {
223
+ target: "otpError",
224
+ guard: "hasAttemptsRemaining",
225
+ actions: assign(({ context }) => ({
226
+ otpError: "Invalid OTP code",
227
+ attemptsRemaining: context.attemptsRemaining - 1
228
+ }))
229
+ },
230
+ {
231
+ target: "error",
232
+ actions: assign({ error: () => "Maximum OTP attempts exceeded" })
233
+ }
234
+ ],
235
+ onError: [{
236
+ target: "otpError",
237
+ guard: "hasAttemptsRemaining",
238
+ actions: "setOtpError"
239
+ }, {
240
+ target: "error",
241
+ actions: "setError"
242
+ }]
243
+ } },
244
+ otpError: { on: {
245
+ OTP_CHANGED: {
246
+ target: "awaitingOtp",
247
+ actions: "setOtpCode"
248
+ },
249
+ RESEND_OTP: {
250
+ target: "sendingOtp",
251
+ guard: "canResend"
252
+ },
253
+ BACK: { target: "inputting" }
254
+ } },
255
+ success: { on: { RESET: {
256
+ target: "idle",
257
+ actions: "resetContext"
258
+ } } },
259
+ error: { on: { RESET: {
260
+ target: "idle",
261
+ actions: "resetContext"
262
+ } } }
263
+ }
264
+ });
265
+
266
+ //#endregion
267
+ //#region src/email/emailActor.ts
268
+ function createEmailActor(options) {
269
+ return createActor(emailMachine, { input: { config: options.config } }).start();
270
+ }
271
+
272
+ //#endregion
273
+ //#region src/email/emailManager.ts
274
+ /**
275
+ * @module @incodetech/core/email
276
+ *
277
+ * Email verification module for the Incode Web SDK.
278
+ * Supports both headless (programmatic) and UI-driven usage patterns.
279
+ *
280
+ * ## Headless Usage
281
+ *
282
+ * The email manager can be used entirely without UI for backend integrations,
283
+ * custom UI implementations, or automated workflows.
284
+ *
285
+ * @example Basic headless email verification with OTP
286
+ * ```typescript
287
+ * import { createEmailManager } from '@incodetech/core/email';
288
+ * import { setup } from '@incodetech/core';
289
+ *
290
+ * // 1. Configure the SDK (required before using any module)
291
+ * setup({ apiURL: 'https://api.example.com', token: 'your-token' });
292
+ *
293
+ * // 2. Create the email manager
294
+ * const emailManager = createEmailManager({
295
+ * config: {
296
+ * otpVerification: true,
297
+ * otpExpirationInMinutes: 5,
298
+ * prefill: false,
299
+ * },
300
+ * });
301
+ *
302
+ * // 3. Subscribe to state changes (optional but recommended)
303
+ * emailManager.subscribe((state) => {
304
+ * console.log('Email state:', state.status);
305
+ * if (state.status === 'success') {
306
+ * console.log('Email verified successfully!');
307
+ * }
308
+ * if (state.status === 'error') {
309
+ * console.error('Error:', state.error);
310
+ * }
311
+ * });
312
+ *
313
+ * // 4. Start the flow
314
+ * emailManager.load();
315
+ *
316
+ * // 5. When state is 'inputting', set the email address
317
+ * emailManager.setEmail('user@example.com', true);
318
+ *
319
+ * // 6. Submit the email address
320
+ * emailManager.submit();
321
+ *
322
+ * // 7. When state is 'awaitingOtp', submit the OTP code
323
+ * emailManager.submitOtp('ABC123');
324
+ *
325
+ * // 8. Clean up when done
326
+ * emailManager.stop();
327
+ * ```
328
+ *
329
+ * @example Polling-based headless usage
330
+ * ```typescript
331
+ * const emailManager = createEmailManager({ config });
332
+ *
333
+ * emailManager.load();
334
+ *
335
+ * // Poll for state changes
336
+ * const interval = setInterval(() => {
337
+ * const state = emailManager.getState();
338
+ *
339
+ * switch (state.status) {
340
+ * case 'inputting':
341
+ * emailManager.setEmail('user@example.com', true);
342
+ * emailManager.submit();
343
+ * break;
344
+ * case 'awaitingOtp':
345
+ * // Get OTP from user or external source
346
+ * emailManager.submitOtp(otpCode);
347
+ * break;
348
+ * case 'success':
349
+ * clearInterval(interval);
350
+ * emailManager.stop();
351
+ * break;
352
+ * case 'error':
353
+ * clearInterval(interval);
354
+ * console.error(state.error);
355
+ * emailManager.stop();
356
+ * break;
357
+ * }
358
+ * }, 100);
359
+ * ```
360
+ */
361
+ function mapState(snapshot) {
362
+ const typedSnapshot = snapshot;
363
+ const { context } = typedSnapshot;
364
+ if (typedSnapshot.matches("idle")) return { status: "idle" };
365
+ if (typedSnapshot.matches("loadingPrefill")) return { status: "loadingPrefill" };
366
+ if (typedSnapshot.matches("inputting")) return {
367
+ status: "inputting",
368
+ prefilledEmail: context.prefilledEmail,
369
+ emailError: context.emailError
370
+ };
371
+ if (typedSnapshot.matches("submitting")) return { status: "submitting" };
372
+ if (typedSnapshot.matches("sendingOtp")) return { status: "sendingOtp" };
373
+ if (typedSnapshot.matches("awaitingOtp")) return {
374
+ status: "awaitingOtp",
375
+ resendTimer: context.resendTimer,
376
+ canResend: !context.resendTimerActive,
377
+ attemptsRemaining: context.attemptsRemaining
378
+ };
379
+ if (typedSnapshot.matches("verifyingOtp")) return { status: "verifyingOtp" };
380
+ if (typedSnapshot.matches("otpError")) return {
381
+ status: "otpError",
382
+ error: context.otpError ?? "Invalid OTP code",
383
+ attemptsRemaining: context.attemptsRemaining
384
+ };
385
+ if (typedSnapshot.matches("success")) return { status: "success" };
386
+ if (typedSnapshot.matches("error")) return {
387
+ status: "error",
388
+ error: context.error ?? "An error occurred"
389
+ };
390
+ return { status: "idle" };
391
+ }
392
+ function createApi({ actor }) {
393
+ return {
394
+ load() {
395
+ actor.send({ type: "LOAD" });
396
+ },
397
+ setEmail(email, isValid) {
398
+ actor.send({
399
+ type: "EMAIL_CHANGED",
400
+ email,
401
+ isValid
402
+ });
403
+ },
404
+ submit() {
405
+ actor.send({ type: "SUBMIT" });
406
+ },
407
+ setOtpCode(code) {
408
+ actor.send({
409
+ type: "OTP_CHANGED",
410
+ code
411
+ });
412
+ },
413
+ submitOtp(code) {
414
+ actor.send({
415
+ type: "OTP_CHANGED",
416
+ code
417
+ });
418
+ actor.send({ type: "VERIFY_OTP" });
419
+ },
420
+ resendOtp() {
421
+ actor.send({ type: "RESEND_OTP" });
422
+ },
423
+ back() {
424
+ actor.send({ type: "BACK" });
425
+ },
426
+ reset() {
427
+ actor.send({ type: "RESET" });
428
+ }
429
+ };
430
+ }
431
+ /**
432
+ * Creates an email verification manager for headless or UI-driven usage.
433
+ *
434
+ * The manager provides a state machine-based API for email address verification
435
+ * with optional OTP (one-time password) verification.
436
+ *
437
+ * @param options - Configuration options
438
+ * @param options.config - Email verification configuration
439
+ * @param options.config.otpVerification - Whether to require OTP verification
440
+ * @param options.config.otpExpirationInMinutes - How long the OTP is valid
441
+ * @param options.config.prefill - Whether to fetch a pre-filled email address
442
+ * @param options.config.maxOtpAttempts - Maximum OTP verification attempts (default: 3)
443
+ *
444
+ * @returns Email manager with state, API methods, and subscription
445
+ *
446
+ * @example Headless usage
447
+ * ```typescript
448
+ * const manager = createEmailManager({
449
+ * config: { otpVerification: true, otpExpirationInMinutes: 5, prefill: false },
450
+ * });
451
+ *
452
+ * manager.subscribe((state) => console.log(state.status));
453
+ * manager.load();
454
+ * manager.setEmail('user@example.com', true);
455
+ * manager.submit();
456
+ * // ... wait for 'awaitingOtp' state ...
457
+ * manager.submitOtp('ABC123');
458
+ * manager.stop();
459
+ * ```
460
+ *
461
+ * @example With React/Preact UI hook
462
+ * ```tsx
463
+ * const [state, manager] = useManager(() => createEmailManager({ config }));
464
+ *
465
+ * if (state.status === 'inputting') {
466
+ * return <input onChange={(e) => manager.setEmail(e.target.value, true)} />;
467
+ * }
468
+ * ```
469
+ */
470
+ function createEmailManager(options) {
471
+ return createManager({
472
+ actor: createEmailActor(options),
473
+ mapState,
474
+ createApi
475
+ });
476
+ }
477
+
478
+ //#endregion
479
+ export { createEmailManager, emailMachine };