@incodetech/core 2.0.0-alpha.2 → 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 (134) hide show
  1. package/package.json +4 -1
  2. package/.turbo/turbo-build.log +0 -33
  3. package/.turbo/turbo-coverage.log +0 -22
  4. package/.turbo/turbo-format.log +0 -6
  5. package/.turbo/turbo-lint$colon$fix.log +0 -77
  6. package/.turbo/turbo-lint.log +0 -95
  7. package/.turbo/turbo-test.log +0 -870
  8. package/.turbo/turbo-typecheck.log +0 -5
  9. package/coverage/base.css +0 -224
  10. package/coverage/block-navigation.js +0 -87
  11. package/coverage/favicon.png +0 -0
  12. package/coverage/index.html +0 -221
  13. package/coverage/prettify.css +0 -1
  14. package/coverage/prettify.js +0 -2
  15. package/coverage/sort-arrow-sprite.png +0 -0
  16. package/coverage/sorter.js +0 -210
  17. package/coverage/src/camera/cameraService.ts.html +0 -580
  18. package/coverage/src/camera/cameraServices.ts.html +0 -163
  19. package/coverage/src/camera/cameraStateMachine.ts.html +0 -877
  20. package/coverage/src/camera/index.html +0 -146
  21. package/coverage/src/email/emailActor.ts.html +0 -130
  22. package/coverage/src/email/emailManager.ts.html +0 -1366
  23. package/coverage/src/email/emailStateMachine.ts.html +0 -1186
  24. package/coverage/src/email/index.html +0 -146
  25. package/coverage/src/flow/flowActor.ts.html +0 -124
  26. package/coverage/src/flow/flowAnalyzer.ts.html +0 -196
  27. package/coverage/src/flow/flowManager.ts.html +0 -790
  28. package/coverage/src/flow/flowServices.ts.html +0 -124
  29. package/coverage/src/flow/flowStateMachine.ts.html +0 -631
  30. package/coverage/src/flow/index.html +0 -221
  31. package/coverage/src/flow/moduleLoader.ts.html +0 -304
  32. package/coverage/src/flow/orchestratedFlowManager.ts.html +0 -778
  33. package/coverage/src/flow/orchestratedFlowStateMachine.ts.html +0 -1060
  34. package/coverage/src/http/api.ts.html +0 -355
  35. package/coverage/src/http/endpoints.ts.html +0 -136
  36. package/coverage/src/http/index.html +0 -131
  37. package/coverage/src/index.html +0 -116
  38. package/coverage/src/phone/index.html +0 -146
  39. package/coverage/src/phone/phoneActor.ts.html +0 -130
  40. package/coverage/src/phone/phoneManager.ts.html +0 -1459
  41. package/coverage/src/phone/phoneStateMachine.ts.html +0 -1351
  42. package/coverage/src/recordings/index.html +0 -116
  43. package/coverage/src/recordings/recordingsRepository.ts.html +0 -229
  44. package/coverage/src/selfie/index.html +0 -191
  45. package/coverage/src/selfie/selfieActor.ts.html +0 -136
  46. package/coverage/src/selfie/selfieErrorUtils.ts.html +0 -283
  47. package/coverage/src/selfie/selfieManager.ts.html +0 -988
  48. package/coverage/src/selfie/selfieStateMachine.ts.html +0 -2497
  49. package/coverage/src/selfie/selfieUploadService.ts.html +0 -328
  50. package/coverage/src/selfie/types.ts.html +0 -394
  51. package/coverage/src/setup.ts.html +0 -598
  52. package/src/camera/cameraActor.ts +0 -21
  53. package/src/camera/cameraService.test.ts +0 -437
  54. package/src/camera/cameraService.ts +0 -165
  55. package/src/camera/cameraServices.test.ts +0 -66
  56. package/src/camera/cameraServices.ts +0 -26
  57. package/src/camera/cameraStateMachine.test.ts +0 -602
  58. package/src/camera/cameraStateMachine.ts +0 -264
  59. package/src/camera/index.ts +0 -5
  60. package/src/camera/types.ts +0 -17
  61. package/src/device/getBrowser.ts +0 -31
  62. package/src/device/getDeviceClass.ts +0 -29
  63. package/src/device/index.ts +0 -2
  64. package/src/email/__mocks__/emailMocks.ts +0 -59
  65. package/src/email/emailActor.ts +0 -15
  66. package/src/email/emailManager.test.ts +0 -573
  67. package/src/email/emailManager.ts +0 -427
  68. package/src/email/emailServices.ts +0 -66
  69. package/src/email/emailStateMachine.test.ts +0 -741
  70. package/src/email/emailStateMachine.ts +0 -367
  71. package/src/email/index.ts +0 -39
  72. package/src/email/types.ts +0 -60
  73. package/src/events/addEvent.ts +0 -20
  74. package/src/events/types.ts +0 -7
  75. package/src/flow/__mocks__/flowMocks.ts +0 -84
  76. package/src/flow/flowActor.ts +0 -13
  77. package/src/flow/flowAnalyzer.test.ts +0 -266
  78. package/src/flow/flowAnalyzer.ts +0 -37
  79. package/src/flow/flowCompletionService.ts +0 -21
  80. package/src/flow/flowManager.test.ts +0 -560
  81. package/src/flow/flowManager.ts +0 -235
  82. package/src/flow/flowServices.test.ts +0 -109
  83. package/src/flow/flowServices.ts +0 -13
  84. package/src/flow/flowStateMachine.test.ts +0 -334
  85. package/src/flow/flowStateMachine.ts +0 -182
  86. package/src/flow/index.ts +0 -21
  87. package/src/flow/moduleLoader.test.ts +0 -136
  88. package/src/flow/moduleLoader.ts +0 -73
  89. package/src/flow/orchestratedFlowManager.test.ts +0 -240
  90. package/src/flow/orchestratedFlowManager.ts +0 -231
  91. package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
  92. package/src/flow/orchestratedFlowStateMachine.ts +0 -325
  93. package/src/flow/types.ts +0 -434
  94. package/src/http/__mocks__/api.ts +0 -88
  95. package/src/http/api.test.ts +0 -231
  96. package/src/http/api.ts +0 -90
  97. package/src/http/endpoints.ts +0 -17
  98. package/src/index.ts +0 -33
  99. package/src/permissions/index.ts +0 -2
  100. package/src/permissions/permissionServices.ts +0 -31
  101. package/src/permissions/types.ts +0 -3
  102. package/src/phone/__mocks__/phoneMocks.ts +0 -71
  103. package/src/phone/index.ts +0 -39
  104. package/src/phone/phoneActor.ts +0 -15
  105. package/src/phone/phoneManager.test.ts +0 -393
  106. package/src/phone/phoneManager.ts +0 -458
  107. package/src/phone/phoneServices.ts +0 -98
  108. package/src/phone/phoneStateMachine.test.ts +0 -918
  109. package/src/phone/phoneStateMachine.ts +0 -422
  110. package/src/phone/types.ts +0 -83
  111. package/src/recordings/recordingsRepository.test.ts +0 -87
  112. package/src/recordings/recordingsRepository.ts +0 -48
  113. package/src/recordings/streamingEvents.ts +0 -10
  114. package/src/selfie/__mocks__/selfieMocks.ts +0 -26
  115. package/src/selfie/index.ts +0 -14
  116. package/src/selfie/selfieActor.ts +0 -17
  117. package/src/selfie/selfieErrorUtils.test.ts +0 -116
  118. package/src/selfie/selfieErrorUtils.ts +0 -66
  119. package/src/selfie/selfieManager.test.ts +0 -297
  120. package/src/selfie/selfieManager.ts +0 -301
  121. package/src/selfie/selfieServices.ts +0 -362
  122. package/src/selfie/selfieStateMachine.test.ts +0 -283
  123. package/src/selfie/selfieStateMachine.ts +0 -804
  124. package/src/selfie/selfieUploadService.test.ts +0 -90
  125. package/src/selfie/selfieUploadService.ts +0 -81
  126. package/src/selfie/types.ts +0 -103
  127. package/src/session/index.ts +0 -5
  128. package/src/session/sessionService.ts +0 -78
  129. package/src/setup.test.ts +0 -61
  130. package/src/setup.ts +0 -171
  131. package/tsconfig.json +0 -13
  132. package/tsdown.config.ts +0 -22
  133. package/vitest.config.ts +0 -37
  134. package/vitest.setup.ts +0 -135
@@ -1,458 +0,0 @@
1
- /**
2
- * @module @incodetech/core/phone
3
- *
4
- * Phone verification module for the Incode Web SDK.
5
- * Supports both headless (programmatic) and UI-driven usage patterns.
6
- *
7
- * ## Headless Usage
8
- *
9
- * The phone manager can be used entirely without UI for backend integrations,
10
- * custom UI implementations, or automated workflows.
11
- *
12
- * @example Basic headless phone verification with OTP
13
- * ```typescript
14
- * import { createPhoneManager } from '@incodetech/core/phone';
15
- * import { setup } from '@incodetech/core';
16
- *
17
- * // 1. Configure the SDK (required before using any module)
18
- * setup({ apiURL: 'https://api.example.com', token: 'your-token' });
19
- *
20
- * // 2. Create the phone manager
21
- * const phoneManager = createPhoneManager({
22
- * config: {
23
- * otpVerification: true,
24
- * otpExpirationInMinutes: 5,
25
- * prefill: false,
26
- * maxOtpAttempts: 3,
27
- * },
28
- * });
29
- *
30
- * // 3. Subscribe to state changes (optional but recommended)
31
- * phoneManager.subscribe((state) => {
32
- * console.log('Phone state:', state.status);
33
- * if (state.status === 'success') {
34
- * console.log('Phone verified successfully!');
35
- * }
36
- * if (state.status === 'error') {
37
- * console.error('Error:', state.error);
38
- * }
39
- * });
40
- *
41
- * // 4. Start the flow
42
- * phoneManager.load();
43
- *
44
- * // 5. When state is 'inputting', set the phone number
45
- * phoneManager.setPhoneNumber('+14155551234', true);
46
- *
47
- * // 6. Submit the phone number
48
- * phoneManager.submit();
49
- *
50
- * // 7. When state is 'awaitingOtp', submit the OTP code
51
- * phoneManager.submitOtp('ABC123');
52
- *
53
- * // 8. Clean up when done
54
- * phoneManager.stop();
55
- * ```
56
- *
57
- * @example Polling-based headless usage
58
- * ```typescript
59
- * const phoneManager = createPhoneManager({ config });
60
- *
61
- * phoneManager.load();
62
- *
63
- * // Poll for state changes
64
- * const interval = setInterval(() => {
65
- * const state = phoneManager.getState();
66
- *
67
- * switch (state.status) {
68
- * case 'inputting':
69
- * phoneManager.setPhoneNumber('+14155551234', true);
70
- * phoneManager.submit();
71
- * break;
72
- * case 'awaitingOtp':
73
- * // Get OTP from user or external source
74
- * phoneManager.submitOtp(otpCode);
75
- * break;
76
- * case 'success':
77
- * clearInterval(interval);
78
- * phoneManager.stop();
79
- * break;
80
- * case 'error':
81
- * clearInterval(interval);
82
- * console.error(state.error);
83
- * phoneManager.stop();
84
- * break;
85
- * }
86
- * }, 100);
87
- * ```
88
- */
89
- import {
90
- type CreateApiOptions,
91
- createManager,
92
- type ManagerSnapshot,
93
- } from '@incodetech/infra';
94
- import { type CreatePhoneActorOptions, createPhoneActor } from './phoneActor';
95
- import type { PhoneMachine } from './phoneStateMachine';
96
-
97
- type PhoneSnapshot = ManagerSnapshot<PhoneMachine>;
98
-
99
- /** Phone manager is in initial state, waiting for `load()` to be called */
100
- export type PhoneIdleState = {
101
- status: 'idle';
102
- };
103
-
104
- /** Loading prefilled phone number from backend (if prefill is enabled) */
105
- export type PhoneLoadingPrefillState = {
106
- status: 'loadingPrefill';
107
- };
108
-
109
- /**
110
- * Ready for phone input - use `setPhoneNumber()` and `submit()`
111
- * @property countryCode - ISO country code (e.g., 'US', 'MX')
112
- * @property phonePrefix - International dialing prefix (e.g., '+1', '+52')
113
- * @property prefilledPhone - Pre-populated phone number (if prefill enabled)
114
- * @property phoneError - Validation error message if phone was rejected
115
- */
116
- export type PhoneInputtingState = {
117
- status: 'inputting';
118
- countryCode: string;
119
- phonePrefix: string;
120
- prefilledPhone?: string;
121
- phoneError?: string;
122
- };
123
-
124
- /** Phone number is being submitted to the backend */
125
- export type PhoneSubmittingState = {
126
- status: 'submitting';
127
- };
128
-
129
- /** OTP is being sent to the phone number */
130
- export type PhoneSendingOtpState = {
131
- status: 'sendingOtp';
132
- };
133
-
134
- /**
135
- * Waiting for OTP code - use `submitOtp()`, `resendOtp()`, or `back()`
136
- * @property resendTimer - Seconds remaining before resend is allowed
137
- * @property canResend - Whether the resend button should be enabled
138
- * @property attemptsRemaining - Number of OTP verification attempts left
139
- */
140
- export type PhoneAwaitingOtpState = {
141
- status: 'awaitingOtp';
142
- resendTimer: number;
143
- canResend: boolean;
144
- attemptsRemaining: number;
145
- };
146
-
147
- /** OTP code is being verified against the backend */
148
- export type PhoneVerifyingOtpState = {
149
- status: 'verifyingOtp';
150
- };
151
-
152
- /**
153
- * OTP verification failed - user can retry with `submitOtp()`
154
- * @property error - Error message describing why verification failed
155
- * @property attemptsRemaining - Number of remaining attempts before lockout
156
- */
157
- export type PhoneOtpErrorState = {
158
- status: 'otpError';
159
- error: string;
160
- attemptsRemaining: number;
161
- };
162
-
163
- /** Phone verification completed successfully - call `reset()` to start over */
164
- export type PhoneSuccessState = {
165
- status: 'success';
166
- };
167
-
168
- /**
169
- * Fatal error occurred - call `reset()` to start over
170
- * @property error - Error message describing what went wrong
171
- */
172
- export type PhoneErrorState = {
173
- status: 'error';
174
- error: string;
175
- };
176
-
177
- /**
178
- * Union of all possible phone manager states.
179
- * Use discriminated union pattern to narrow the type:
180
- *
181
- * @example
182
- * ```typescript
183
- * const state = phoneManager.getState();
184
- * if (state.status === 'inputting') {
185
- * // TypeScript knows state has countryCode, phonePrefix, etc.
186
- * console.log(state.countryCode);
187
- * }
188
- * ```
189
- */
190
- export type PhoneState =
191
- | PhoneIdleState
192
- | PhoneLoadingPrefillState
193
- | PhoneInputtingState
194
- | PhoneSubmittingState
195
- | PhoneSendingOtpState
196
- | PhoneAwaitingOtpState
197
- | PhoneVerifyingOtpState
198
- | PhoneOtpErrorState
199
- | PhoneSuccessState
200
- | PhoneErrorState;
201
-
202
- function mapState(snapshot: PhoneSnapshot): PhoneState {
203
- // Type assertion needed because PhoneMachine uses 'as any' for declaration file generation
204
- const typedSnapshot = snapshot as PhoneSnapshot & {
205
- matches: (state: string) => boolean;
206
- context: {
207
- countryCode: string;
208
- phonePrefix: string;
209
- prefilledPhone?: string;
210
- phoneError?: string;
211
- resendTimer: number;
212
- resendTimerActive: boolean;
213
- attemptsRemaining: number;
214
- otpError?: string;
215
- error?: string;
216
- };
217
- };
218
- const { context } = typedSnapshot;
219
-
220
- if (typedSnapshot.matches('idle')) {
221
- return { status: 'idle' };
222
- }
223
-
224
- if (typedSnapshot.matches('loadingPrefill')) {
225
- return { status: 'loadingPrefill' };
226
- }
227
-
228
- if (typedSnapshot.matches('loadingStartInfo')) {
229
- return {
230
- status: 'inputting',
231
- countryCode: context.countryCode,
232
- phonePrefix: context.phonePrefix,
233
- prefilledPhone: context.prefilledPhone,
234
- };
235
- }
236
-
237
- if (typedSnapshot.matches('inputting')) {
238
- return {
239
- status: 'inputting',
240
- countryCode: context.countryCode,
241
- phonePrefix: context.phonePrefix,
242
- prefilledPhone: context.prefilledPhone,
243
- phoneError: context.phoneError,
244
- };
245
- }
246
-
247
- if (typedSnapshot.matches('submitting')) {
248
- return { status: 'submitting' };
249
- }
250
-
251
- if (typedSnapshot.matches('sendingOtp')) {
252
- return { status: 'sendingOtp' };
253
- }
254
-
255
- if (typedSnapshot.matches('awaitingOtp')) {
256
- return {
257
- status: 'awaitingOtp',
258
- resendTimer: context.resendTimer,
259
- canResend: !context.resendTimerActive,
260
- attemptsRemaining: context.attemptsRemaining,
261
- };
262
- }
263
-
264
- if (typedSnapshot.matches('verifyingOtp')) {
265
- return { status: 'verifyingOtp' };
266
- }
267
-
268
- if (typedSnapshot.matches('otpError')) {
269
- return {
270
- status: 'otpError',
271
- error: context.otpError ?? 'Invalid OTP code',
272
- attemptsRemaining: context.attemptsRemaining,
273
- };
274
- }
275
-
276
- if (typedSnapshot.matches('success')) {
277
- return { status: 'success' };
278
- }
279
-
280
- if (typedSnapshot.matches('error')) {
281
- return {
282
- status: 'error',
283
- error: context.error ?? 'An error occurred',
284
- };
285
- }
286
-
287
- return { status: 'idle' };
288
- }
289
-
290
- function createApi({ actor }: CreateApiOptions<PhoneMachine>) {
291
- return {
292
- /**
293
- * Initializes the phone verification flow.
294
- * Transitions from 'idle' to 'loadingPrefill' or 'inputting'.
295
- * Must be called before any other method.
296
- */
297
- load() {
298
- actor.send({ type: 'LOAD' });
299
- },
300
-
301
- /**
302
- * Sets the phone number for verification.
303
- * Should be called when state is 'inputting'.
304
- *
305
- * @param phone - Full phone number with country code (e.g., '+14155551234')
306
- * @param isValid - Whether the phone number passes validation
307
- *
308
- * @example
309
- * ```typescript
310
- * // Using libphonenumber-js for validation
311
- * import { isValidPhoneNumber } from 'libphonenumber-js';
312
- * const phone = '+14155551234';
313
- * phoneManager.setPhoneNumber(phone, isValidPhoneNumber(phone));
314
- * ```
315
- */
316
- setPhoneNumber(phone: string, isValid: boolean) {
317
- actor.send({ type: 'PHONE_CHANGED', phone, isValid });
318
- },
319
-
320
- /**
321
- * Sets the marketing opt-in preference.
322
- * Only relevant if `config.optinEnabled` is true.
323
- *
324
- * @param granted - Whether the user consented to receive marketing messages
325
- */
326
- setOptInGranted(granted: boolean) {
327
- actor.send({ type: 'OPT_IN_CHANGED', granted });
328
- },
329
-
330
- /**
331
- * Submits the phone number for verification.
332
- * Requires a valid phone number to be set via `setPhoneNumber()`.
333
- * Transitions to 'submitting', then to 'sendingOtp' or 'success' (if no OTP).
334
- */
335
- submit() {
336
- actor.send({ type: 'SUBMIT' });
337
- },
338
-
339
- /**
340
- * Sets the OTP code without submitting.
341
- * Use this for controlled input components.
342
- *
343
- * @param code - The OTP code entered by the user
344
- */
345
- setOtpCode(code: string) {
346
- actor.send({ type: 'OTP_CHANGED', code });
347
- },
348
-
349
- /**
350
- * Sets and submits the OTP code in one call.
351
- * Should be called when state is 'awaitingOtp' or 'otpError'.
352
- *
353
- * @param code - The complete OTP code (typically 6 alphanumeric characters)
354
- *
355
- * @example
356
- * ```typescript
357
- * // Submit OTP when user completes entry
358
- * phoneManager.submitOtp('HH36LP');
359
- * ```
360
- */
361
- submitOtp(code: string) {
362
- actor.send({ type: 'OTP_CHANGED', code });
363
- actor.send({ type: 'VERIFY_OTP' });
364
- },
365
-
366
- /**
367
- * Requests a new OTP code to be sent.
368
- * Only works when state is 'awaitingOtp' and `canResend` is true.
369
- * Resets the resend timer.
370
- */
371
- resendOtp() {
372
- actor.send({ type: 'RESEND_OTP' });
373
- },
374
-
375
- /**
376
- * Returns to the phone input screen from OTP entry.
377
- * Allows the user to change their phone number.
378
- * Transitions from 'awaitingOtp' or 'otpError' back to 'inputting'.
379
- */
380
- back() {
381
- actor.send({ type: 'BACK' });
382
- },
383
-
384
- /**
385
- * Resets the manager to initial state.
386
- * Can be called from 'success' or 'error' states to start over.
387
- * Clears all stored data including phone number and OTP.
388
- */
389
- reset() {
390
- actor.send({ type: 'RESET' });
391
- },
392
- };
393
- }
394
-
395
- /**
396
- * Creates a phone verification manager for headless or UI-driven usage.
397
- *
398
- * The manager provides a state machine-based API for phone number verification
399
- * with optional OTP (one-time password) verification.
400
- *
401
- * @param options - Configuration options
402
- * @param options.config - Phone verification configuration
403
- * @param options.config.otpVerification - Whether to require OTP verification
404
- * @param options.config.otpExpirationInMinutes - How long the OTP is valid
405
- * @param options.config.prefill - Whether to fetch a pre-filled phone number
406
- * @param options.config.isInstantVerify - Use instant verification API
407
- * @param options.config.optinEnabled - Show marketing opt-in checkbox
408
- * @param options.config.maxOtpAttempts - Maximum OTP verification attempts (default: 3)
409
- *
410
- * @returns Phone manager with state, API methods, and subscription
411
- *
412
- * @example Headless usage
413
- * ```typescript
414
- * const manager = createPhoneManager({
415
- * config: { otpVerification: true, otpExpirationInMinutes: 5, prefill: false },
416
- * });
417
- *
418
- * manager.subscribe((state) => console.log(state.status));
419
- * manager.load();
420
- * manager.setPhoneNumber('+14155551234', true);
421
- * manager.submit();
422
- * // ... wait for 'awaitingOtp' state ...
423
- * manager.submitOtp('ABC123');
424
- * manager.stop();
425
- * ```
426
- *
427
- * @example With React/Preact UI hook
428
- * ```tsx
429
- * const [state, manager] = useManager(() => createPhoneManager({ config }));
430
- *
431
- * if (state.status === 'inputting') {
432
- * return <input onChange={(e) => manager.setPhoneNumber(e.target.value, true)} />;
433
- * }
434
- * ```
435
- */
436
- export function createPhoneManager(options: CreatePhoneActorOptions) {
437
- const actor = createPhoneActor(options);
438
- return createManager({ actor, mapState, createApi });
439
- }
440
-
441
- /**
442
- * Type representing a phone manager instance.
443
- * Includes state access, API methods, and lifecycle management.
444
- *
445
- * @property getState - Returns the current PhoneState
446
- * @property subscribe - Subscribes to state changes, returns unsubscribe function
447
- * @property stop - Stops the manager and cleans up resources
448
- * @property load - Initializes the verification flow
449
- * @property setPhoneNumber - Sets the phone number
450
- * @property setOptInGranted - Sets marketing opt-in preference
451
- * @property submit - Submits the phone number
452
- * @property setOtpCode - Sets OTP code without submitting
453
- * @property submitOtp - Sets and submits OTP code
454
- * @property resendOtp - Requests new OTP code
455
- * @property back - Returns to phone input from OTP screen
456
- * @property reset - Resets to initial state
457
- */
458
- export type PhoneManager = ReturnType<typeof createPhoneManager>;
@@ -1,98 +0,0 @@
1
- import { api } from '../http/api';
2
- import { endpoints } from '../http/endpoints';
3
- import type {
4
- AddPhoneParams,
5
- AddPhoneResponse,
6
- StartInfo,
7
- VerifyOtpResponse,
8
- } from './types';
9
-
10
- export async function fetchPhone(
11
- signal?: AbortSignal,
12
- ): Promise<{ phone: string }> {
13
- const res = await api.get<{ phone: string }>(endpoints.getPhone, { signal });
14
- if (!res.ok) {
15
- throw new Error(
16
- `GET ${endpoints.getPhone} failed: ${res.status} ${res.statusText}`,
17
- );
18
- }
19
- return res.data as { phone: string };
20
- }
21
-
22
- export async function fetchStartInfo(signal?: AbortSignal): Promise<StartInfo> {
23
- const res = await api.get<StartInfo>(endpoints.startInfo, { signal });
24
- if (!res.ok) {
25
- throw new Error(
26
- `GET ${endpoints.startInfo} failed: ${res.status} ${res.statusText}`,
27
- );
28
- }
29
- return res.data as StartInfo;
30
- }
31
-
32
- export async function addPhone(
33
- params: AddPhoneParams,
34
- signal?: AbortSignal,
35
- ): Promise<AddPhoneResponse> {
36
- const res = await api.post<AddPhoneResponse>(
37
- endpoints.phone,
38
- {
39
- phone: params.phone,
40
- optInGranted: params.optInGranted,
41
- },
42
- { signal },
43
- );
44
- if (!res.ok) {
45
- throw new Error(
46
- `POST ${endpoints.phone} failed: ${res.status} ${res.statusText}`,
47
- );
48
- }
49
- return res.data as AddPhoneResponse;
50
- }
51
-
52
- export async function addPhoneInstantVerify(
53
- params: AddPhoneParams,
54
- signal?: AbortSignal,
55
- ): Promise<AddPhoneResponse> {
56
- const res = await api.post<AddPhoneResponse>(
57
- endpoints.phoneInstant,
58
- {
59
- phone: params.phone,
60
- optInGranted: params.optInGranted,
61
- },
62
- { signal },
63
- );
64
- if (!res.ok) {
65
- throw new Error(
66
- `POST ${endpoints.phoneInstant} failed: ${res.status} ${res.statusText}`,
67
- );
68
- }
69
- return res.data as AddPhoneResponse;
70
- }
71
-
72
- export async function sendOtp(signal?: AbortSignal): Promise<void> {
73
- const res = await api.get(
74
- `${endpoints.sendSmsOtp}?communicationchannel=SMS`,
75
- { signal },
76
- );
77
- if (!res.ok) {
78
- throw new Error(
79
- `GET ${endpoints.sendSmsOtp} failed: ${res.status} ${res.statusText}`,
80
- );
81
- }
82
- }
83
-
84
- export async function verifyOtp(
85
- code: string,
86
- signal?: AbortSignal,
87
- ): Promise<VerifyOtpResponse> {
88
- const res = await api.get<VerifyOtpResponse>(
89
- `${endpoints.compareOtp}?code=${code}&channel=SMS`,
90
- { signal },
91
- );
92
- if (!res.ok) {
93
- throw new Error(
94
- `GET ${endpoints.compareOtp} failed: ${res.status} ${res.statusText}`,
95
- );
96
- }
97
- return res.data as VerifyOtpResponse;
98
- }