@incodetech/core 2.0.0-alpha.2 → 2.0.0-alpha.4

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 (154) hide show
  1. package/dist/OpenViduLogger-BdPfiZO6.esm.js +3 -0
  2. package/dist/OpenViduLogger-CQyDxBvM.esm.js +803 -0
  3. package/dist/{addEvent-1Mi5CEiq.esm.js → addEvent-9v4w5iO-.esm.js} +1 -1
  4. package/dist/email.d.ts +1 -1
  5. package/dist/email.esm.js +2 -2
  6. package/dist/{endpoints-D_pUMaqA.esm.js → endpoints-Dn1t57hJ.esm.js} +8 -3
  7. package/dist/flow.d.ts +3 -3
  8. package/dist/flow.esm.js +1 -1
  9. package/dist/index.d.ts +2 -2
  10. package/dist/index.esm.js +2 -2
  11. package/dist/{lib-CyIAFRfr.esm.js → lib-Bu9XGMBW.esm.js} +1 -800
  12. package/dist/{permissionServices-CVR0Pq38.esm.js → permissionServices-CCpxd8le.esm.js} +1 -1
  13. package/dist/phone.d.ts +1 -1
  14. package/dist/phone.esm.js +2 -2
  15. package/dist/selfie.d.ts +5 -4
  16. package/dist/selfie.esm.js +27 -10
  17. package/package.json +4 -1
  18. package/.turbo/turbo-build.log +0 -33
  19. package/.turbo/turbo-coverage.log +0 -22
  20. package/.turbo/turbo-format.log +0 -6
  21. package/.turbo/turbo-lint$colon$fix.log +0 -77
  22. package/.turbo/turbo-lint.log +0 -95
  23. package/.turbo/turbo-test.log +0 -870
  24. package/.turbo/turbo-typecheck.log +0 -5
  25. package/coverage/base.css +0 -224
  26. package/coverage/block-navigation.js +0 -87
  27. package/coverage/favicon.png +0 -0
  28. package/coverage/index.html +0 -221
  29. package/coverage/prettify.css +0 -1
  30. package/coverage/prettify.js +0 -2
  31. package/coverage/sort-arrow-sprite.png +0 -0
  32. package/coverage/sorter.js +0 -210
  33. package/coverage/src/camera/cameraService.ts.html +0 -580
  34. package/coverage/src/camera/cameraServices.ts.html +0 -163
  35. package/coverage/src/camera/cameraStateMachine.ts.html +0 -877
  36. package/coverage/src/camera/index.html +0 -146
  37. package/coverage/src/email/emailActor.ts.html +0 -130
  38. package/coverage/src/email/emailManager.ts.html +0 -1366
  39. package/coverage/src/email/emailStateMachine.ts.html +0 -1186
  40. package/coverage/src/email/index.html +0 -146
  41. package/coverage/src/flow/flowActor.ts.html +0 -124
  42. package/coverage/src/flow/flowAnalyzer.ts.html +0 -196
  43. package/coverage/src/flow/flowManager.ts.html +0 -790
  44. package/coverage/src/flow/flowServices.ts.html +0 -124
  45. package/coverage/src/flow/flowStateMachine.ts.html +0 -631
  46. package/coverage/src/flow/index.html +0 -221
  47. package/coverage/src/flow/moduleLoader.ts.html +0 -304
  48. package/coverage/src/flow/orchestratedFlowManager.ts.html +0 -778
  49. package/coverage/src/flow/orchestratedFlowStateMachine.ts.html +0 -1060
  50. package/coverage/src/http/api.ts.html +0 -355
  51. package/coverage/src/http/endpoints.ts.html +0 -136
  52. package/coverage/src/http/index.html +0 -131
  53. package/coverage/src/index.html +0 -116
  54. package/coverage/src/phone/index.html +0 -146
  55. package/coverage/src/phone/phoneActor.ts.html +0 -130
  56. package/coverage/src/phone/phoneManager.ts.html +0 -1459
  57. package/coverage/src/phone/phoneStateMachine.ts.html +0 -1351
  58. package/coverage/src/recordings/index.html +0 -116
  59. package/coverage/src/recordings/recordingsRepository.ts.html +0 -229
  60. package/coverage/src/selfie/index.html +0 -191
  61. package/coverage/src/selfie/selfieActor.ts.html +0 -136
  62. package/coverage/src/selfie/selfieErrorUtils.ts.html +0 -283
  63. package/coverage/src/selfie/selfieManager.ts.html +0 -988
  64. package/coverage/src/selfie/selfieStateMachine.ts.html +0 -2497
  65. package/coverage/src/selfie/selfieUploadService.ts.html +0 -328
  66. package/coverage/src/selfie/types.ts.html +0 -394
  67. package/coverage/src/setup.ts.html +0 -598
  68. package/src/camera/cameraActor.ts +0 -21
  69. package/src/camera/cameraService.test.ts +0 -437
  70. package/src/camera/cameraService.ts +0 -165
  71. package/src/camera/cameraServices.test.ts +0 -66
  72. package/src/camera/cameraServices.ts +0 -26
  73. package/src/camera/cameraStateMachine.test.ts +0 -602
  74. package/src/camera/cameraStateMachine.ts +0 -264
  75. package/src/camera/index.ts +0 -5
  76. package/src/camera/types.ts +0 -17
  77. package/src/device/getBrowser.ts +0 -31
  78. package/src/device/getDeviceClass.ts +0 -29
  79. package/src/device/index.ts +0 -2
  80. package/src/email/__mocks__/emailMocks.ts +0 -59
  81. package/src/email/emailActor.ts +0 -15
  82. package/src/email/emailManager.test.ts +0 -573
  83. package/src/email/emailManager.ts +0 -427
  84. package/src/email/emailServices.ts +0 -66
  85. package/src/email/emailStateMachine.test.ts +0 -741
  86. package/src/email/emailStateMachine.ts +0 -367
  87. package/src/email/index.ts +0 -39
  88. package/src/email/types.ts +0 -60
  89. package/src/events/addEvent.ts +0 -20
  90. package/src/events/types.ts +0 -7
  91. package/src/flow/__mocks__/flowMocks.ts +0 -84
  92. package/src/flow/flowActor.ts +0 -13
  93. package/src/flow/flowAnalyzer.test.ts +0 -266
  94. package/src/flow/flowAnalyzer.ts +0 -37
  95. package/src/flow/flowCompletionService.ts +0 -21
  96. package/src/flow/flowManager.test.ts +0 -560
  97. package/src/flow/flowManager.ts +0 -235
  98. package/src/flow/flowServices.test.ts +0 -109
  99. package/src/flow/flowServices.ts +0 -13
  100. package/src/flow/flowStateMachine.test.ts +0 -334
  101. package/src/flow/flowStateMachine.ts +0 -182
  102. package/src/flow/index.ts +0 -21
  103. package/src/flow/moduleLoader.test.ts +0 -136
  104. package/src/flow/moduleLoader.ts +0 -73
  105. package/src/flow/orchestratedFlowManager.test.ts +0 -240
  106. package/src/flow/orchestratedFlowManager.ts +0 -231
  107. package/src/flow/orchestratedFlowStateMachine.test.ts +0 -199
  108. package/src/flow/orchestratedFlowStateMachine.ts +0 -325
  109. package/src/flow/types.ts +0 -434
  110. package/src/http/__mocks__/api.ts +0 -88
  111. package/src/http/api.test.ts +0 -231
  112. package/src/http/api.ts +0 -90
  113. package/src/http/endpoints.ts +0 -17
  114. package/src/index.ts +0 -33
  115. package/src/permissions/index.ts +0 -2
  116. package/src/permissions/permissionServices.ts +0 -31
  117. package/src/permissions/types.ts +0 -3
  118. package/src/phone/__mocks__/phoneMocks.ts +0 -71
  119. package/src/phone/index.ts +0 -39
  120. package/src/phone/phoneActor.ts +0 -15
  121. package/src/phone/phoneManager.test.ts +0 -393
  122. package/src/phone/phoneManager.ts +0 -458
  123. package/src/phone/phoneServices.ts +0 -98
  124. package/src/phone/phoneStateMachine.test.ts +0 -918
  125. package/src/phone/phoneStateMachine.ts +0 -422
  126. package/src/phone/types.ts +0 -83
  127. package/src/recordings/recordingsRepository.test.ts +0 -87
  128. package/src/recordings/recordingsRepository.ts +0 -48
  129. package/src/recordings/streamingEvents.ts +0 -10
  130. package/src/selfie/__mocks__/selfieMocks.ts +0 -26
  131. package/src/selfie/index.ts +0 -14
  132. package/src/selfie/selfieActor.ts +0 -17
  133. package/src/selfie/selfieErrorUtils.test.ts +0 -116
  134. package/src/selfie/selfieErrorUtils.ts +0 -66
  135. package/src/selfie/selfieManager.test.ts +0 -297
  136. package/src/selfie/selfieManager.ts +0 -301
  137. package/src/selfie/selfieServices.ts +0 -362
  138. package/src/selfie/selfieStateMachine.test.ts +0 -283
  139. package/src/selfie/selfieStateMachine.ts +0 -804
  140. package/src/selfie/selfieUploadService.test.ts +0 -90
  141. package/src/selfie/selfieUploadService.ts +0 -81
  142. package/src/selfie/types.ts +0 -103
  143. package/src/session/index.ts +0 -5
  144. package/src/session/sessionService.ts +0 -78
  145. package/src/setup.test.ts +0 -61
  146. package/src/setup.ts +0 -171
  147. package/tsconfig.json +0 -13
  148. package/tsdown.config.ts +0 -22
  149. package/vitest.config.ts +0 -37
  150. package/vitest.setup.ts +0 -135
  151. /package/dist/{Manager-6BwbaI_H.d.ts → Manager-BGfxEmyv.d.ts} +0 -0
  152. /package/dist/{StateMachine-7c1gcu94.d.ts → StateMachine-DRE1oH2B.d.ts} +0 -0
  153. /package/dist/{types-tq1ypYSL.d.ts → types-kWlqshfM.d.ts} +0 -0
  154. /package/dist/{warmup-Dr7OcFND.d.ts → warmup-CEJTfxQr.d.ts} +0 -0
@@ -1,90 +0,0 @@
1
- import { describe, expect, it, vi } from 'vitest';
2
- import { uploadSelfie } from './selfieUploadService';
3
- import { FACE_ERROR_CODES } from './types';
4
-
5
- vi.mock('../device', () => ({
6
- getDeviceClass: vi.fn(() => 'desktop'),
7
- }));
8
-
9
- vi.mock('../http/api', () => ({
10
- api: {
11
- post: vi.fn(),
12
- },
13
- }));
14
-
15
- describe('selfieUploadService', () => {
16
- it('returns data on success', async () => {
17
- const { api } = await import('../http/api');
18
- vi.mocked(api.post).mockResolvedValueOnce({
19
- ok: true,
20
- status: 200,
21
- statusText: 'OK',
22
- url: 'x',
23
- headers: {},
24
- data: {
25
- age: 1,
26
- confidence: 0,
27
- hasClosedEyes: false,
28
- hasFaceMask: false,
29
- hasHeadCover: false,
30
- hasLenses: false,
31
- isBright: true,
32
- liveness: true,
33
- imageBase64: '',
34
- sessionStatus: 'ok',
35
- },
36
- });
37
-
38
- await expect(
39
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
40
- ).resolves.toMatchObject({ confidence: 0, sessionStatus: 'ok' });
41
- });
42
-
43
- it('maps HTTP 400 status 4019 to FACE_NOT_FOUND', async () => {
44
- const { api } = await import('../http/api');
45
- vi.mocked(api.post).mockRejectedValueOnce({
46
- ok: false,
47
- status: 400,
48
- data: { status: 4019 },
49
- });
50
-
51
- await expect(
52
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
53
- ).rejects.toThrow(FACE_ERROR_CODES.FACE_NOT_FOUND);
54
- });
55
-
56
- it('maps HTTP 400 with missing backend status to BAD_REQUEST', async () => {
57
- const { api } = await import('../http/api');
58
- vi.mocked(api.post).mockRejectedValueOnce({
59
- ok: false,
60
- status: 400,
61
- data: {},
62
- });
63
-
64
- await expect(
65
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
66
- ).rejects.toThrow(FACE_ERROR_CODES.BAD_REQUEST);
67
- });
68
-
69
- it('maps non-400 HTTP error to SERVER_ERROR', async () => {
70
- const { api } = await import('../http/api');
71
- vi.mocked(api.post).mockRejectedValueOnce({
72
- ok: false,
73
- status: 500,
74
- data: { status: 9999 },
75
- });
76
-
77
- await expect(
78
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
79
- ).rejects.toThrow(FACE_ERROR_CODES.SERVER);
80
- });
81
-
82
- it('maps unknown error shapes to SERVER_ERROR', async () => {
83
- const { api } = await import('../http/api');
84
- vi.mocked(api.post).mockRejectedValueOnce(new Error('boom'));
85
-
86
- await expect(
87
- uploadSelfie({ encryptedBase64Image: 'abc', faceCoordinates: undefined }),
88
- ).rejects.toThrow(FACE_ERROR_CODES.SERVER);
89
- });
90
- });
@@ -1,81 +0,0 @@
1
- import type { FaceCoordinates } from '@incodetech/infra';
2
- import { getDeviceClass } from '../device';
3
- import { api } from '../http/api';
4
- import { endpoints } from '../http/endpoints';
5
- import type { FaceErrorCode, SendFaceImageResponse } from './types';
6
- import { FACE_ERROR_CODES } from './types';
7
-
8
- export type UploadSelfieParams = {
9
- encryptedBase64Image: string;
10
- faceCoordinates?: FaceCoordinates;
11
- signal?: AbortSignal;
12
- };
13
-
14
- /**
15
- * Uploads a selfie image to the backend.
16
- */
17
- export async function uploadSelfie({
18
- encryptedBase64Image,
19
- faceCoordinates,
20
- signal,
21
- }: UploadSelfieParams): Promise<SendFaceImageResponse> {
22
- try {
23
- const res = await api.post<SendFaceImageResponse>(
24
- endpoints.selfie,
25
- {
26
- base64Image: encryptedBase64Image,
27
- faceCoordinates: faceCoordinates ?? undefined,
28
- encrypted: true,
29
- clientInfo: { deviceClass: getDeviceClass() },
30
- },
31
- { signal, query: { imageType: 'selfie' } },
32
- );
33
- if (!res.ok) {
34
- throw new Error(
35
- `POST ${endpoints.selfie} failed: ${res.status} ${res.statusText}`,
36
- );
37
- }
38
- return res.data as SendFaceImageResponse;
39
- } catch (error) {
40
- const errorCode = getFaceErrorCodeFromHttpError(error);
41
- if (errorCode) {
42
- throw new Error(errorCode);
43
- }
44
- throw new Error(FACE_ERROR_CODES.SERVER);
45
- }
46
- }
47
-
48
- const getFaceErrorCodeFromHttpError = (
49
- error: unknown,
50
- ): FaceErrorCode | undefined => {
51
- const err = error as {
52
- ok?: boolean;
53
- status?: number;
54
- data?: { status?: number };
55
- };
56
-
57
- if (err.ok !== false || typeof err.status !== 'number') {
58
- return undefined;
59
- }
60
-
61
- if (err.status !== 400) {
62
- return FACE_ERROR_CODES.SERVER;
63
- }
64
-
65
- if (typeof err.data?.status !== 'number') {
66
- return FACE_ERROR_CODES.BAD_REQUEST;
67
- }
68
-
69
- const errorMap: Record<number, FaceErrorCode> = {
70
- 3004: FACE_ERROR_CODES.FACE_NOT_FOUND,
71
- 3005: FACE_ERROR_CODES.FACE_NOT_FOUND,
72
- 3006: FACE_ERROR_CODES.TOO_BLURRY,
73
- 3007: FACE_ERROR_CODES.TOO_DARK,
74
- 4010: FACE_ERROR_CODES.MULTIPLE_FACES,
75
- 4019: FACE_ERROR_CODES.FACE_NOT_FOUND,
76
- 4077: FACE_ERROR_CODES.BAD_PHOTO_QUALITY,
77
- 4078: FACE_ERROR_CODES.FACE_OCCLUDED,
78
- };
79
-
80
- return errorMap[err.data.status] ?? FACE_ERROR_CODES.BAD_REQUEST;
81
- };
@@ -1,103 +0,0 @@
1
- import type {
2
- IRecordingCapability,
3
- RecordingConnection,
4
- } from '@incodetech/infra';
5
-
6
- export type { PermissionResult, PermissionStatus } from '../permissions/types';
7
-
8
- export type SelfieConfig = {
9
- showTutorial: boolean;
10
- showPreview: boolean;
11
- assistedOnboarding: boolean;
12
- enableFaceRecording: boolean;
13
- recording?: {
14
- capability?: IRecordingCapability;
15
- };
16
- autoCaptureTimeout: number;
17
- captureAttempts: number;
18
- validateLenses: boolean;
19
- validateFaceMask: boolean;
20
- validateHeadCover: boolean;
21
- validateClosedEyes: boolean;
22
- validateBrightness: boolean;
23
- deepsightLiveness: 'SINGLE_FRAME' | 'MULTIMODAL' | 'VIDEOLIVENESS';
24
- };
25
-
26
- export type DetectionStatus =
27
- | 'idle'
28
- | 'detecting'
29
- | 'noFace'
30
- | 'tooManyFaces'
31
- | 'tooClose'
32
- | 'tooFar'
33
- | 'blur'
34
- | 'dark'
35
- | 'faceAngle'
36
- | 'headWear'
37
- | 'lenses'
38
- | 'eyesClosed'
39
- | 'faceMask'
40
- | 'centerFace'
41
- | 'manualCapture'
42
- | 'success'
43
- | 'error'
44
- | 'capturing'
45
- | 'getReady'
46
- | 'getReadyFinished'
47
- | 'offline';
48
-
49
- export type SendFaceImageResponse = {
50
- age: number;
51
- confidence: number;
52
- hasClosedEyes: boolean;
53
- hasFaceMask: boolean;
54
- hasHeadCover: boolean;
55
- hasLenses: boolean;
56
- isBright: boolean;
57
- liveness: boolean;
58
- imageBase64: string;
59
- sessionStatus: string;
60
- };
61
-
62
- export const FACE_ERROR_CODES = {
63
- FACE_OCCLUDED: 'FACE_OCCLUDED',
64
- LIVENESS: 'LIVENESS_ERROR',
65
- BRIGHTNESS: 'BRIGHTNESS_ERROR',
66
- LENSES: 'LENSES_ERROR',
67
- MASK: 'MASK_ERROR',
68
- CLOSED_EYES: 'CLOSED_EYES_ERROR',
69
- HEAD_COVER: 'HEAD_COVER_ERROR',
70
- SERVER: 'SERVER_ERROR',
71
- FACE_NOT_FOUND: 'FACE_NOT_FOUND',
72
- MULTIPLE_FACES: 'MULTIPLE_FACES',
73
- TOO_BLURRY: 'TOO_BLURRY_ERROR',
74
- TOO_DARK: 'TOO_DARK_ERROR',
75
- USER_IS_NOT_RECOGNIZED: 'USER_IS_NOT_RECOGNIZED',
76
- SPOOF_ATTEMPT_DETECTED: 'SPOOF_ATTEMPT_DETECTED',
77
- FACE_TOO_DARK: 'FACE_TOO_DARK',
78
- LENSES_DETECTED: 'LENSES_DETECTED',
79
- FACE_MASK_DETECTED: 'FACE_MASK_DETECTED',
80
- CLOSED_EYES_DETECTED: 'CLOSED_EYES_DETECTED',
81
- HEAD_COVER_DETECTED: 'HEAD_COVER_DETECTED',
82
- FACE_CROPPING_FAILED: 'FACE_CROPPING_FAILED',
83
- FACE_TOO_SMALL: 'FACE_TOO_SMALL',
84
- FACE_TOO_BLURRY: 'FACE_TOO_BLURRY',
85
- BAD_PHOTO_QUALITY: 'BAD_PHOTO_QUALITY',
86
- PROCESSING_ERROR: 'PROCESSING_ERROR',
87
- BAD_REQUEST: 'BAD_REQUEST',
88
- NONEXISTENT_CUSTOMER: 'NONEXISTENT_CUSTOMER',
89
- HINT_NOT_PROVIDED: 'HINT_NOT_PROVIDED',
90
- SELFIE_IMAGE_LOW_QUALITY: 'SELFIE_IMAGE_LOW_QUALITY',
91
- } as const;
92
-
93
- export type FaceErrorCode =
94
- (typeof FACE_ERROR_CODES)[keyof typeof FACE_ERROR_CODES];
95
-
96
- export type RecordingSession = {
97
- token: string;
98
- sessionId: string;
99
- videoRecordingId: string;
100
- connection: RecordingConnection;
101
- resolution?: string;
102
- hasAudio: boolean;
103
- };
@@ -1,5 +0,0 @@
1
- export {
2
- type CreateSessionOptions,
3
- createSession,
4
- type Session,
5
- } from './sessionService';
@@ -1,78 +0,0 @@
1
- import { getApi } from '../http/api';
2
- import { endpoints } from '../http/endpoints';
3
-
4
- export type CreateSessionOptions = {
5
- /** The configuration/flow ID from the Incode dashboard */
6
- configurationId: string;
7
- /** External ID to associate with this session */
8
- externalId?: string;
9
- /** External customer ID */
10
- externalCustomerId?: string;
11
- /** Language for the session (e.g., 'en-US', 'es-MX') */
12
- language?: string;
13
- /** Custom fields to attach to the session */
14
- customFields?: Record<string, unknown>;
15
- /** UUID for continuing an existing session */
16
- uuid?: string;
17
- /** Interview ID for continuing an existing interview */
18
- interviewId?: string;
19
- };
20
-
21
- export type Session = {
22
- token: string;
23
- interviewId: string;
24
- uuid?: string;
25
- regulationType?: string;
26
- showMandatoryConsent?: boolean;
27
- };
28
-
29
- /**
30
- * Creates a new onboarding session.
31
- *
32
- * @param apiKey - The API key from the Incode dashboard
33
- * @param options - Session creation options
34
- * @param signal - Optional AbortSignal for request cancellation
35
- * @returns The created session with token
36
- *
37
- * @example
38
- * ```ts
39
- * const session = await createSession('your-api-key', {
40
- * configurationId: 'your-flow-id',
41
- * language: 'en-US',
42
- * });
43
- * console.log(session.token); // Use this token for subsequent API calls
44
- * ```
45
- */
46
- export async function createSession(
47
- apiKey: string,
48
- options: CreateSessionOptions,
49
- signal?: AbortSignal,
50
- ): Promise<Session> {
51
- const res = await getApi().post<Session>(
52
- endpoints.createSession,
53
- {
54
- configurationId: options.configurationId,
55
- externalId: options.externalId,
56
- externalCustomerId: options.externalCustomerId,
57
- language: options.language ?? 'en-US',
58
- customFields: options.customFields,
59
- uuid: options.uuid ?? null,
60
- interviewId: options.interviewId ?? null,
61
- },
62
- {
63
- headers: {
64
- 'x-api-key': apiKey,
65
- 'api-version': '1.0',
66
- },
67
- signal,
68
- },
69
- );
70
-
71
- if (!res.ok) {
72
- throw new Error(
73
- `POST ${endpoints.createSession} failed: ${res.status} ${res.statusText}`,
74
- );
75
- }
76
-
77
- return res.data as Session;
78
- }
package/src/setup.test.ts DELETED
@@ -1,61 +0,0 @@
1
- import { beforeEach, describe, expect, it } from 'vitest';
2
- import { getApi, getToken } from './http/api';
3
- import { isConfigured, reset, setup } from './setup';
4
-
5
- describe('setup', () => {
6
- beforeEach(() => {
7
- reset();
8
- });
9
-
10
- describe('setup()', () => {
11
- it('should configure the SDK with apiURL and token', () => {
12
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
13
-
14
- expect(isConfigured()).toBe(true);
15
- });
16
-
17
- it('should configure the SDK with custom headers', () => {
18
- setup({
19
- apiURL: 'https://api.test.com',
20
- token: 'test-token',
21
- customHeaders: { 'X-Custom': 'value' },
22
- });
23
-
24
- const client = getApi();
25
- expect(client.defaults.headers['X-Custom']).toBe('value');
26
- expect(getToken()).toBe('test-token');
27
- });
28
-
29
- it('should configure the SDK with timeout', () => {
30
- setup({
31
- apiURL: 'https://api.test.com',
32
- token: 'test-token',
33
- timeout: 5000,
34
- });
35
-
36
- expect(isConfigured()).toBe(true);
37
- });
38
- });
39
-
40
- describe('isConfigured()', () => {
41
- it('should return false before setup()', () => {
42
- expect(isConfigured()).toBe(false);
43
- });
44
-
45
- it('should return true after setup()', () => {
46
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
47
-
48
- expect(isConfigured()).toBe(true);
49
- });
50
- });
51
-
52
- describe('reset()', () => {
53
- it('should reset the SDK', () => {
54
- setup({ apiURL: 'https://api.test.com', token: 'test-token' });
55
- expect(isConfigured()).toBe(true);
56
-
57
- reset();
58
- expect(isConfigured()).toBe(false);
59
- });
60
- });
61
- });
package/src/setup.ts DELETED
@@ -1,171 +0,0 @@
1
- import {
2
- createApi,
3
- type WasmPipeline,
4
- WasmUtilProvider,
5
- warmupWasm,
6
- } from '@incodetech/infra';
7
- import { resetApi, setClient, setToken } from './http/api';
8
-
9
- /**
10
- * WASM warmup configuration.
11
- */
12
- export type WasmConfig = {
13
- /** Path to the WASM binary */
14
- wasmPath: string;
15
- /** Path to the SIMD-optimized WASM binary (optional) */
16
- wasmSimdPath?: string;
17
- /** Path to the WASM glue code */
18
- glueCodePath: string;
19
- /** Whether to use SIMD optimizations (default: true) */
20
- useSimd?: boolean;
21
- /** Which pipelines to preload models for */
22
- pipelines?: WasmPipeline[];
23
- /**
24
- * Base path for ML model files. Models will be loaded from `${modelsBasePath}/${modelFileName}`.
25
- * If not provided, models are expected in a 'models' subdirectory relative to the WASM binary.
26
- */
27
- modelsBasePath?: string;
28
- };
29
-
30
- let wasmConfig: WasmConfig | undefined;
31
-
32
- /**
33
- * Configuration options for the SDK setup.
34
- */
35
- export type SetupOptions = {
36
- /** The base URL for the API */
37
- apiURL: string;
38
- /** The session token for API requests (optional - can be set later or omitted for createSession calls) */
39
- token?: string;
40
- /** Custom headers to include in all requests */
41
- customHeaders?: Record<string, string>;
42
- /** Request timeout in milliseconds */
43
- timeout?: number;
44
- /** Optional WASM warmup config - if provided, preloads WASM and ML models */
45
- wasm?: WasmConfig;
46
- };
47
-
48
- let configured = false;
49
-
50
- /**
51
- * Initializes the SDK with the provided configuration.
52
- * Must be called before using any SDK functionality.
53
- *
54
- * If `wasm` config is provided, this function becomes async and will
55
- * preload WASM binary and ML models. Otherwise, it's synchronous.
56
- *
57
- * @param options - Configuration options for the SDK
58
- *
59
- * @example
60
- * ```ts
61
- * import { setup, createSession } from '@incodetech/core';
62
- *
63
- * // Setup with API URL first (for session creation)
64
- * await setup({ apiURL: 'https://api.incode.com' });
65
- * const session = await createSession('api-key', { configurationId: 'flow-id' });
66
- *
67
- * // Basic setup with token
68
- * await setup({
69
- * apiURL: 'https://api.incode.com',
70
- * token: 'session-token',
71
- * });
72
- *
73
- * // Setup with WASM warmup
74
- * await setup({
75
- * apiURL: 'https://api.incode.com',
76
- * token: 'session-token',
77
- * wasm: {
78
- * wasmPath: '/wasm/ml-wasm.wasm',
79
- * glueCodePath: '/wasm/ml-wasm.js',
80
- * pipelines: ['selfie', 'idCapture'],
81
- * },
82
- * });
83
- * ```
84
- */
85
- export async function setup(options: SetupOptions): Promise<void> {
86
- const client = createApi({
87
- apiURL: options.apiURL,
88
- customHeaders: options.customHeaders,
89
- timeout: options.timeout,
90
- });
91
- setClient(client);
92
- if (options.token) {
93
- setToken(options.token);
94
- }
95
- configured = true;
96
-
97
- if (options.wasm) {
98
- await warmupWasm({
99
- wasmPath: options.wasm.wasmPath,
100
- wasmSimdPath: options.wasm.wasmSimdPath,
101
- glueCodePath: options.wasm.glueCodePath,
102
- useSimd: options.wasm.useSimd,
103
- pipelines: options.wasm.pipelines,
104
- modelsBasePath: options.wasm.modelsBasePath,
105
- });
106
-
107
- const provider = await WasmUtilProvider.getInstance();
108
- await provider.initialize({
109
- wasmPath: options.wasm.wasmPath,
110
- wasmSimdPath: options.wasm.wasmSimdPath,
111
- glueCodePath: options.wasm.glueCodePath,
112
- useSimd: options.wasm.useSimd,
113
- pipelines: options.wasm.pipelines,
114
- modelsBasePath: options.wasm.modelsBasePath,
115
- });
116
- }
117
- }
118
-
119
- /**
120
- * Sets the WASM configuration without performing warmup.
121
- * Useful when WASM warmup is handled separately (e.g., conditionally based on flow).
122
- *
123
- * @param config - WASM configuration to store
124
- */
125
- export function setWasmConfig(config: WasmConfig): void {
126
- wasmConfig = config;
127
- }
128
-
129
- /**
130
- * Initializes WasmUtilProvider with the stored WASM configuration.
131
- * Should be called after warmupWasm() completes when using conditional warmup.
132
- * This ensures image encryption works properly.
133
- *
134
- * @param config - Optional WASM configuration. If not provided, uses the stored config from setWasmConfig().
135
- * @throws Error if no config is provided and none is stored
136
- */
137
- export async function initializeWasmUtil(config?: WasmConfig): Promise<void> {
138
- const wasmConfigToUse = config ?? wasmConfig;
139
- if (!wasmConfigToUse) {
140
- throw new Error(
141
- 'WASM config is required. Provide config parameter or call setWasmConfig() first.',
142
- );
143
- }
144
- const provider = await WasmUtilProvider.getInstance();
145
- await provider.initialize({
146
- wasmPath: wasmConfigToUse.wasmPath,
147
- wasmSimdPath: wasmConfigToUse.wasmSimdPath,
148
- glueCodePath: wasmConfigToUse.glueCodePath,
149
- useSimd: wasmConfigToUse.useSimd,
150
- pipelines: wasmConfigToUse.pipelines,
151
- modelsBasePath: wasmConfigToUse.modelsBasePath,
152
- });
153
- }
154
-
155
- /**
156
- * Checks if the SDK has been configured.
157
- *
158
- * @returns true if setup() has been called, false otherwise
159
- */
160
- export function isConfigured(): boolean {
161
- return configured;
162
- }
163
-
164
- /**
165
- * Resets the SDK configuration. Useful for testing.
166
- */
167
- export function reset(): void {
168
- resetApi();
169
- configured = false;
170
- WasmUtilProvider.resetInstance();
171
- }
package/tsconfig.json DELETED
@@ -1,13 +0,0 @@
1
- {
2
- "extends": "../config/ts/tsconfig.strict.json",
3
- "compilerOptions": {
4
- "outDir": "dist",
5
- "paths": {
6
- "@incodetech/config/*": ["../config/*"],
7
- "@incodetech/infra": ["../infra/src"],
8
- "@incodetech/infra/*": ["../infra/src/*"]
9
- }
10
- },
11
- "include": ["src"],
12
- "exclude": ["node_modules", "dist"]
13
- }
package/tsdown.config.ts DELETED
@@ -1,22 +0,0 @@
1
- import { defineConfig } from 'tsdown';
2
-
3
- export default defineConfig({
4
- format: ['esm'],
5
- dts: {
6
- sourcemap: false,
7
- },
8
- sourcemap: false,
9
- clean: true,
10
- target: 'es2021',
11
- outDir: 'dist',
12
- outExtensions: () => ({ js: '.esm.js', dts: '.d.ts' }),
13
- entry: {
14
- index: 'src/index.ts',
15
- flow: 'src/flow/index.ts',
16
- selfie: 'src/selfie/index.ts',
17
- phone: 'src/phone/index.ts',
18
- email: 'src/email/index.ts',
19
- },
20
- noExternal: ['@incodetech/infra'],
21
- platform: 'browser',
22
- });
package/vitest.config.ts DELETED
@@ -1,37 +0,0 @@
1
- import { dirname, resolve } from 'node:path';
2
- import { fileURLToPath, pathToFileURL } from 'node:url';
3
- import { defineConfig, mergeConfig } from 'vitest/config';
4
-
5
- const __dirname = dirname(fileURLToPath(import.meta.url));
6
- const baseConfigUrl = pathToFileURL(
7
- resolve(__dirname, '../config/vitest/base.ts'),
8
- ).href;
9
- const baseConfig = await import(baseConfigUrl);
10
-
11
- export default mergeConfig(
12
- baseConfig.default,
13
- defineConfig({
14
- resolve: {
15
- alias: {
16
- '@incodetech/config': resolve(__dirname, '../config'),
17
- '@incodetech/infra': resolve(__dirname, '../infra/src'),
18
- },
19
- },
20
- test: {
21
- environment: 'node',
22
- setupFiles: ['./vitest.setup.ts'],
23
- coverage: {
24
- exclude: ['**/__mocks__/**', '**/id/**'],
25
- thresholds: {
26
- // Camera module has async flows that are hard to test reliably
27
- // The state machine transitions happen asynchronously and
28
- // the permission API cannot be easily mocked in Node.js
29
- lines: 45,
30
- functions: 75,
31
- branches: 20,
32
- statements: 45,
33
- },
34
- },
35
- },
36
- }),
37
- );