@moveris/shared 2.6.0 → 2.7.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 CHANGED
@@ -26,7 +26,7 @@ const client = new LivenessClient({
26
26
  // Perform a fast liveness check
27
27
  const result = await client.fastCheck(frames, {
28
28
  sessionId: 'my-session-id', // optional — auto-generated if omitted
29
- model: '10',
29
+ model: 'mixed-10-v2',
30
30
  source: 'live',
31
31
  });
32
32
 
@@ -64,18 +64,18 @@ Perform fast liveness check with server-side face detection. Ideal for quick ver
64
64
  ```typescript
65
65
  const result = await client.fastCheck(frames, {
66
66
  sessionId: 'optional-uuid',
67
- model: '10', // '10' | '50' | '250'
67
+ model: 'mixed-10-v2',
68
68
  source: 'live', // 'live' | 'media'
69
69
  });
70
70
  ```
71
71
 
72
72
  **Parameters:**
73
73
 
74
- | Option | Type | Default | Description |
75
- | ----------- | ---------------- | -------------- | ----------------------------------------------------------------------- |
76
- | `sessionId` | `string` | auto-generated | Unique session identifier (UUID) |
77
- | `model` | `FastCheckModel` | `'10'` | Model to use: `'10'` (fast), `'50'` (balanced), `'250'` (high-accuracy) |
78
- | `source` | `FrameSource` | `'live'` | Frame source: `'live'` (camera) or `'media'` (recorded video) |
74
+ | Option | Type | Default | Description |
75
+ | ----------- | ---------------- | --------------- | ------------------------------------------------------------- |
76
+ | `sessionId` | `string` | auto-generated | Unique session identifier (UUID) |
77
+ | `model` | `FastCheckModel` | `'mixed-10-v2'` | Model to use (see Models section) |
78
+ | `source` | `FrameSource` | `'live'` | Frame source: `'live'` (camera) or `'media'` (recorded video) |
79
79
 
80
80
  **Returns:** `Promise<LivenessResult>`
81
81
 
@@ -184,22 +184,34 @@ Model selection for liveness detection speed/accuracy trade-off.
184
184
 
185
185
  ```typescript
186
186
  type FastCheckModel =
187
+ | 'mixed-10-v2'
188
+ | 'mixed-30-v2'
189
+ | 'mixed-60-v2'
190
+ | 'mixed-90-v2'
191
+ | 'mixed-120-v2' // Active mixed-v2 models (recommended)
187
192
  | '10'
188
193
  | '50'
189
- | '250' // Standard models
190
- | 'hybrid-v2-10'
191
- | 'hybrid-v2-50' // Hybrid V2 (physiological features)
192
- | 'mixed-10'; // Mixed (visual + physiological scoring)
194
+ | '250' // Legacy standard models
195
+ | (string & object); // Forward-compatible with future model IDs
193
196
  ```
194
197
 
195
- | Value | Frames | Category | Description |
196
- | ---------------- | ------ | --------- | ----------------------------------------- |
197
- | `'10'` | 10 | Standard | Fast verification, lowest latency |
198
- | `'50'` | 50 | Standard | Balanced speed and accuracy |
199
- | `'250'` | 250 | Standard | Highest accuracy, slower |
200
- | `'hybrid-v2-10'` | 10 | Hybrid V2 | Visual + physiological feature extraction |
201
- | `'hybrid-v2-50'` | 50 | Hybrid V2 | Higher accuracy physiological features |
202
- | `'mixed-10'` | 10 | Mixed | Combined visual + physiological scoring |
198
+ Active models (recommended):
199
+
200
+ | Value | Frames | Description |
201
+ | ---------------- | ------ | ------------------------------ |
202
+ | `'mixed-10-v2'` | 10 | Fast verification, low latency |
203
+ | `'mixed-30-v2'` | 30 | Balanced speed and accuracy |
204
+ | `'mixed-60-v2'` | 60 | Higher accuracy |
205
+ | `'mixed-90-v2'` | 90 | High accuracy |
206
+ | `'mixed-120-v2'` | 120 | Highest accuracy, slower |
207
+
208
+ Legacy models (still supported):
209
+
210
+ | Value | Frames | Description |
211
+ | ------- | ------ | --------------------------- |
212
+ | `'10'` | 10 | Standard — fast |
213
+ | `'50'` | 50 | Standard — balanced |
214
+ | `'250'` | 250 | Standard — highest accuracy |
203
215
 
204
216
  #### FrameSource
205
217
 
@@ -492,6 +504,8 @@ const glareRatio = detectSpecularHighlights(pixels);
492
504
  | Glare | `maxGlareRatio: 0.15` | >15% of pixels are specular highlights |
493
505
  | Occluded | `minContrast: 12` | Standard deviation of luminance too low |
494
506
 
507
+ Glare detection uses a **relative threshold** (`mean brightness × 2.5`) so sensitivity adapts to ambient lighting, avoiding false positives in bright environments.
508
+
495
509
  Custom thresholds can be passed as a second argument to `checkEyeRegionQuality()`.
496
510
 
497
511
  ### Eye Region Landmarks
package/dist/index.d.mts CHANGED
@@ -29,6 +29,7 @@ interface FastCheckRequest {
29
29
  model?: FastCheckModel;
30
30
  source?: FrameSource;
31
31
  frames: FrameData[];
32
+ warnings?: string[];
32
33
  }
33
34
  interface FastCheckCropsRequest {
34
35
  session_id: string;
@@ -64,6 +65,7 @@ interface FastCheckStreamRequest {
64
65
  model?: FastCheckModel;
65
66
  source?: FrameSource;
66
67
  frame: FrameData;
68
+ warnings?: string[];
67
69
  }
68
70
  interface FastCheckResponse {
69
71
  verdict: Verdict | null;
@@ -76,6 +78,7 @@ interface FastCheckResponse {
76
78
  frames_processed: number;
77
79
  available: boolean;
78
80
  warning: string | null;
81
+ warnings?: string[] | null;
79
82
  error: string | null;
80
83
  }
81
84
  interface FastCheckStreamResponse {
@@ -93,6 +96,7 @@ interface FastCheckStreamResponse {
93
96
  frames_processed: number | null;
94
97
  available: boolean;
95
98
  warning: string | null;
99
+ warnings?: string[] | null;
96
100
  error: string | null;
97
101
  }
98
102
  interface VerifyResponse {
@@ -157,6 +161,7 @@ interface LivenessResult {
157
161
  sessionId: string;
158
162
  processingMs: number;
159
163
  framesProcessed: number;
164
+ warnings?: string[];
160
165
  }
161
166
  type LivenessState = 'idle' | 'capturing' | 'uploading' | 'processing' | 'complete' | 'error';
162
167
  interface LivenessConfig {
@@ -477,22 +482,26 @@ declare class LivenessClient {
477
482
  sessionId?: string;
478
483
  model?: FastCheckModel;
479
484
  source?: FrameSource;
485
+ warnings?: string[];
480
486
  }): Promise<LivenessResult>;
481
487
  fastCheckCrops(crops: CropData[], options?: {
482
488
  sessionId?: string;
483
489
  model?: FastCheckModel;
484
490
  source?: FrameSource;
491
+ warnings?: string[];
485
492
  }): Promise<LivenessResult>;
486
493
  streamFrame(frame: CapturedFrame, options: {
487
494
  sessionId: string;
488
495
  model?: FastCheckModel;
489
496
  source?: FrameSource;
497
+ warnings?: string[];
490
498
  }): Promise<FastCheckStreamResponse>;
491
499
  private sendStreamFrameInternal;
492
500
  fastCheckStream(frames: CapturedFrame[], options?: {
493
501
  sessionId?: string;
494
502
  model?: FastCheckModel;
495
503
  source?: FrameSource;
504
+ warnings?: string[];
496
505
  }, callbacks?: {
497
506
  onFrameSent?: (index: number, total: number) => void;
498
507
  onFrameBuffered?: (framesReceived: number, framesRequired: number) => void;
@@ -501,6 +510,7 @@ declare class LivenessClient {
501
510
  sessionId?: string;
502
511
  model?: FastCheckModel;
503
512
  source?: FrameSource;
513
+ warnings?: string[];
504
514
  }, callbacks?: {
505
515
  onFrameSent?: (index: number, total: number) => void;
506
516
  onFrameBuffered?: (framesReceived: number, framesRequired: number) => void;
@@ -771,13 +781,13 @@ interface EyeQualityThresholds {
771
781
  minBrightness: number;
772
782
  maxBrightness: number;
773
783
  minContrast: number;
774
- glarePixelThreshold: number;
784
+ glareRelativeFactor: number;
775
785
  maxGlareRatio: number;
776
786
  }
777
787
  declare const EYE_QUALITY_THRESHOLDS: EyeQualityThresholds;
778
788
  declare function analyzeEyeRegionBrightness(pixels: Uint8Array | Uint8ClampedArray): number;
779
789
  declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray, meanBrightness?: number): number;
780
- declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, threshold?: number): number;
790
+ declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
781
791
  declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
782
792
 
783
793
  export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectFaceRoll, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.d.ts CHANGED
@@ -29,6 +29,7 @@ interface FastCheckRequest {
29
29
  model?: FastCheckModel;
30
30
  source?: FrameSource;
31
31
  frames: FrameData[];
32
+ warnings?: string[];
32
33
  }
33
34
  interface FastCheckCropsRequest {
34
35
  session_id: string;
@@ -64,6 +65,7 @@ interface FastCheckStreamRequest {
64
65
  model?: FastCheckModel;
65
66
  source?: FrameSource;
66
67
  frame: FrameData;
68
+ warnings?: string[];
67
69
  }
68
70
  interface FastCheckResponse {
69
71
  verdict: Verdict | null;
@@ -76,6 +78,7 @@ interface FastCheckResponse {
76
78
  frames_processed: number;
77
79
  available: boolean;
78
80
  warning: string | null;
81
+ warnings?: string[] | null;
79
82
  error: string | null;
80
83
  }
81
84
  interface FastCheckStreamResponse {
@@ -93,6 +96,7 @@ interface FastCheckStreamResponse {
93
96
  frames_processed: number | null;
94
97
  available: boolean;
95
98
  warning: string | null;
99
+ warnings?: string[] | null;
96
100
  error: string | null;
97
101
  }
98
102
  interface VerifyResponse {
@@ -157,6 +161,7 @@ interface LivenessResult {
157
161
  sessionId: string;
158
162
  processingMs: number;
159
163
  framesProcessed: number;
164
+ warnings?: string[];
160
165
  }
161
166
  type LivenessState = 'idle' | 'capturing' | 'uploading' | 'processing' | 'complete' | 'error';
162
167
  interface LivenessConfig {
@@ -477,22 +482,26 @@ declare class LivenessClient {
477
482
  sessionId?: string;
478
483
  model?: FastCheckModel;
479
484
  source?: FrameSource;
485
+ warnings?: string[];
480
486
  }): Promise<LivenessResult>;
481
487
  fastCheckCrops(crops: CropData[], options?: {
482
488
  sessionId?: string;
483
489
  model?: FastCheckModel;
484
490
  source?: FrameSource;
491
+ warnings?: string[];
485
492
  }): Promise<LivenessResult>;
486
493
  streamFrame(frame: CapturedFrame, options: {
487
494
  sessionId: string;
488
495
  model?: FastCheckModel;
489
496
  source?: FrameSource;
497
+ warnings?: string[];
490
498
  }): Promise<FastCheckStreamResponse>;
491
499
  private sendStreamFrameInternal;
492
500
  fastCheckStream(frames: CapturedFrame[], options?: {
493
501
  sessionId?: string;
494
502
  model?: FastCheckModel;
495
503
  source?: FrameSource;
504
+ warnings?: string[];
496
505
  }, callbacks?: {
497
506
  onFrameSent?: (index: number, total: number) => void;
498
507
  onFrameBuffered?: (framesReceived: number, framesRequired: number) => void;
@@ -501,6 +510,7 @@ declare class LivenessClient {
501
510
  sessionId?: string;
502
511
  model?: FastCheckModel;
503
512
  source?: FrameSource;
513
+ warnings?: string[];
504
514
  }, callbacks?: {
505
515
  onFrameSent?: (index: number, total: number) => void;
506
516
  onFrameBuffered?: (framesReceived: number, framesRequired: number) => void;
@@ -771,13 +781,13 @@ interface EyeQualityThresholds {
771
781
  minBrightness: number;
772
782
  maxBrightness: number;
773
783
  minContrast: number;
774
- glarePixelThreshold: number;
784
+ glareRelativeFactor: number;
775
785
  maxGlareRatio: number;
776
786
  }
777
787
  declare const EYE_QUALITY_THRESHOLDS: EyeQualityThresholds;
778
788
  declare function analyzeEyeRegionBrightness(pixels: Uint8Array | Uint8ClampedArray): number;
779
789
  declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray, meanBrightness?: number): number;
780
- declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, threshold?: number): number;
790
+ declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
781
791
  declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
782
792
 
783
793
  export { ALIGNMENT_THRESHOLD_CAPTURE, ALIGNMENT_THRESHOLD_GOOD, ALIGNMENT_THRESHOLD_PERFECT, ALIGNMENT_THRESHOLD_POOR, API_ENDPOINTS, API_ERROR_CODES, API_PATHS, AUTH_CONFIG, type ApiErrorCode, BACKLIT_RATIO_THRESHOLD, BLUR_THRESHOLD_MOBILE, BaseFrameCollector, type BlurAnalysis, type CaptureQualityState, type CapturedFrame, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_ENDPOINT, DEFAULT_FACE_DETECTION_TIERS, DEFAULT_GAZE_THRESHOLDS, DEFAULT_HAND_OCCLUSION_CONFIG, DEFAULT_LIVENESS_CONFIG, DEFAULT_LOCALE, DEFAULT_OVAL_REGION, DEFAULT_STABILIZER_CONFIG, DEFAULT_STATUS_MESSAGES, type DetectionResult, type DetectionSummary, type DetectorConfig, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_BOTTOM_MARGIN, MIN_FACE_RATIO, MIN_FACE_SIDE_MARGIN, MIN_FACE_TOP_MARGIN, MIN_IDEAL_FACE_RATIO, MIN_LANDMARK_COUNT, MODEL_CONFIGS, type ModelConfig, type ModelEntry, type ModelType, type ModelsResponse, OVAL_GUIDE_COLORS, OVAL_GUIDE_STYLES, OVAL_REGION_DESKTOP, OVAL_REGION_MOBILE, type OnErrorCallback, type OnFrameCapturedCallback, type OnProgressCallback, type OnResultCallback, type OnStateChangeCallback, type OvalGuideState, type OvalRegion, type QueueStatsResponse, RETRY_CONFIG, type RetryOptions, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateAdaptiveCropMultiplier, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, decodeBase64, detectFaceRoll, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, retryWithBackoff, rgbaToGrayscale, sleep, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.js CHANGED
@@ -261,7 +261,8 @@ function toLivenessResult(response) {
261
261
  score: response.score ?? 0,
262
262
  sessionId: response.session_id,
263
263
  processingMs: response.processing_ms,
264
- framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0
264
+ framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0,
265
+ warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0
265
266
  };
266
267
  }
267
268
  function toLivenessResultFromStream(response) {
@@ -278,7 +279,8 @@ function toLivenessResultFromStream(response) {
278
279
  score: response.score ?? 0,
279
280
  sessionId: response.session_id,
280
281
  processingMs: response.processing_ms ?? 0,
281
- framesProcessed: response.frames_processed ?? 0
282
+ framesProcessed: response.frames_processed ?? 0,
283
+ warnings: Array.isArray(response.warnings) ? response.warnings : void 0
282
284
  };
283
285
  }
284
286
  function generateSessionId() {
@@ -457,7 +459,8 @@ var LivenessClient = class _LivenessClient {
457
459
  session_id: options.sessionId ?? generateSessionId(),
458
460
  model: options.model ?? "10",
459
461
  source: options.source ?? "live",
460
- frames: toFrameData(frames)
462
+ frames: toFrameData(frames),
463
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
461
464
  };
462
465
  const response = await this.requestWithRetry(API_PATHS.fastCheck, {
463
466
  method: "POST",
@@ -477,7 +480,8 @@ var LivenessClient = class _LivenessClient {
477
480
  session_id: options.sessionId ?? generateSessionId(),
478
481
  model: options.model ?? "10",
479
482
  source: options.source ?? "live",
480
- crops
483
+ crops,
484
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
481
485
  };
482
486
  const response = await this.requestWithRetry(API_PATHS.fastCheckCrops, {
483
487
  method: "POST",
@@ -511,7 +515,8 @@ var LivenessClient = class _LivenessClient {
511
515
  return this.sendStreamFrameInternal(frameData, {
512
516
  sessionId: options.sessionId,
513
517
  model: options.model ?? "10",
514
- source: options.source ?? "live"
518
+ source: options.source ?? "live",
519
+ warnings: options.warnings
515
520
  });
516
521
  }
517
522
  /**
@@ -526,7 +531,8 @@ var LivenessClient = class _LivenessClient {
526
531
  session_id: options.sessionId,
527
532
  model: options.model,
528
533
  source: options.source,
529
- frame: frameData
534
+ frame: frameData,
535
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
530
536
  };
531
537
  return this.requestWithRetry(API_PATHS.fastCheckStream, {
532
538
  method: "POST",
@@ -555,7 +561,8 @@ var LivenessClient = class _LivenessClient {
555
561
  const response = await this.sendStreamFrameInternal(frameData, {
556
562
  sessionId,
557
563
  model,
558
- source
564
+ source,
565
+ warnings: options.warnings
559
566
  });
560
567
  callbacks?.onFrameSent?.(index + 1, total);
561
568
  if (response.status === "buffering") {
@@ -604,7 +611,8 @@ var LivenessClient = class _LivenessClient {
604
611
  const response = await this.sendStreamFrameInternal(frameData, {
605
612
  sessionId,
606
613
  model,
607
- source
614
+ source,
615
+ warnings: options.warnings
608
616
  });
609
617
  const currentIndex = frameData.index;
610
618
  callbacks?.onFrameSent?.(currentIndex + 1, total);
@@ -1880,7 +1888,7 @@ var EYE_QUALITY_THRESHOLDS = {
1880
1888
  minBrightness: 40,
1881
1889
  maxBrightness: 230,
1882
1890
  minContrast: 12,
1883
- glarePixelThreshold: 240,
1891
+ glareRelativeFactor: 2.5,
1884
1892
  maxGlareRatio: 0.15
1885
1893
  };
1886
1894
  function rgbaToLuminance(r, g, b) {
@@ -1907,9 +1915,11 @@ function analyzeEyeRegionContrast(pixels, meanBrightness) {
1907
1915
  }
1908
1916
  return Math.sqrt(sumSqDiff / pixelCount);
1909
1917
  }
1910
- function detectSpecularHighlights(pixels, threshold = EYE_QUALITY_THRESHOLDS.glarePixelThreshold) {
1918
+ function detectSpecularHighlights(pixels, relativeFactor = EYE_QUALITY_THRESHOLDS.glareRelativeFactor, meanBrightness) {
1911
1919
  const pixelCount = pixels.length / 4;
1912
1920
  if (pixelCount === 0) return 0;
1921
+ const mean = meanBrightness ?? analyzeEyeRegionBrightness(pixels);
1922
+ const threshold = mean * relativeFactor;
1913
1923
  let glareCount = 0;
1914
1924
  for (let i = 0; i < pixels.length; i += 4) {
1915
1925
  const lum = rgbaToLuminance(pixels[i], pixels[i + 1], pixels[i + 2]);
@@ -1932,7 +1942,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
1932
1942
  }
1933
1943
  const brightness = analyzeEyeRegionBrightness(pixels);
1934
1944
  const contrast = analyzeEyeRegionContrast(pixels, brightness);
1935
- const glareRatio = detectSpecularHighlights(pixels, thresholds.glarePixelThreshold);
1945
+ const glareRatio = detectSpecularHighlights(pixels, thresholds.glareRelativeFactor, brightness);
1936
1946
  const hasGlare = glareRatio > thresholds.maxGlareRatio;
1937
1947
  if (brightness < thresholds.minBrightness) {
1938
1948
  return {
@@ -1954,16 +1964,6 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
1954
1964
  message: "Eye region overexposed - reduce lighting"
1955
1965
  };
1956
1966
  }
1957
- if (hasGlare) {
1958
- return {
1959
- passed: false,
1960
- brightness,
1961
- contrast,
1962
- hasGlare,
1963
- glareRatio,
1964
- message: "Glare detected - adjust angle or remove glasses"
1965
- };
1966
- }
1967
1967
  if (contrast < thresholds.minContrast) {
1968
1968
  return {
1969
1969
  passed: false,
package/dist/index.mjs CHANGED
@@ -128,7 +128,8 @@ function toLivenessResult(response) {
128
128
  score: response.score ?? 0,
129
129
  sessionId: response.session_id,
130
130
  processingMs: response.processing_ms,
131
- framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0
131
+ framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0,
132
+ warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0
132
133
  };
133
134
  }
134
135
  function toLivenessResultFromStream(response) {
@@ -145,7 +146,8 @@ function toLivenessResultFromStream(response) {
145
146
  score: response.score ?? 0,
146
147
  sessionId: response.session_id,
147
148
  processingMs: response.processing_ms ?? 0,
148
- framesProcessed: response.frames_processed ?? 0
149
+ framesProcessed: response.frames_processed ?? 0,
150
+ warnings: Array.isArray(response.warnings) ? response.warnings : void 0
149
151
  };
150
152
  }
151
153
  function generateSessionId() {
@@ -324,7 +326,8 @@ var LivenessClient = class _LivenessClient {
324
326
  session_id: options.sessionId ?? generateSessionId(),
325
327
  model: options.model ?? "10",
326
328
  source: options.source ?? "live",
327
- frames: toFrameData(frames)
329
+ frames: toFrameData(frames),
330
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
328
331
  };
329
332
  const response = await this.requestWithRetry(API_PATHS.fastCheck, {
330
333
  method: "POST",
@@ -344,7 +347,8 @@ var LivenessClient = class _LivenessClient {
344
347
  session_id: options.sessionId ?? generateSessionId(),
345
348
  model: options.model ?? "10",
346
349
  source: options.source ?? "live",
347
- crops
350
+ crops,
351
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
348
352
  };
349
353
  const response = await this.requestWithRetry(API_PATHS.fastCheckCrops, {
350
354
  method: "POST",
@@ -378,7 +382,8 @@ var LivenessClient = class _LivenessClient {
378
382
  return this.sendStreamFrameInternal(frameData, {
379
383
  sessionId: options.sessionId,
380
384
  model: options.model ?? "10",
381
- source: options.source ?? "live"
385
+ source: options.source ?? "live",
386
+ warnings: options.warnings
382
387
  });
383
388
  }
384
389
  /**
@@ -393,7 +398,8 @@ var LivenessClient = class _LivenessClient {
393
398
  session_id: options.sessionId,
394
399
  model: options.model,
395
400
  source: options.source,
396
- frame: frameData
401
+ frame: frameData,
402
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
397
403
  };
398
404
  return this.requestWithRetry(API_PATHS.fastCheckStream, {
399
405
  method: "POST",
@@ -422,7 +428,8 @@ var LivenessClient = class _LivenessClient {
422
428
  const response = await this.sendStreamFrameInternal(frameData, {
423
429
  sessionId,
424
430
  model,
425
- source
431
+ source,
432
+ warnings: options.warnings
426
433
  });
427
434
  callbacks?.onFrameSent?.(index + 1, total);
428
435
  if (response.status === "buffering") {
@@ -471,7 +478,8 @@ var LivenessClient = class _LivenessClient {
471
478
  const response = await this.sendStreamFrameInternal(frameData, {
472
479
  sessionId,
473
480
  model,
474
- source
481
+ source,
482
+ warnings: options.warnings
475
483
  });
476
484
  const currentIndex = frameData.index;
477
485
  callbacks?.onFrameSent?.(currentIndex + 1, total);
@@ -1747,7 +1755,7 @@ var EYE_QUALITY_THRESHOLDS = {
1747
1755
  minBrightness: 40,
1748
1756
  maxBrightness: 230,
1749
1757
  minContrast: 12,
1750
- glarePixelThreshold: 240,
1758
+ glareRelativeFactor: 2.5,
1751
1759
  maxGlareRatio: 0.15
1752
1760
  };
1753
1761
  function rgbaToLuminance(r, g, b) {
@@ -1774,9 +1782,11 @@ function analyzeEyeRegionContrast(pixels, meanBrightness) {
1774
1782
  }
1775
1783
  return Math.sqrt(sumSqDiff / pixelCount);
1776
1784
  }
1777
- function detectSpecularHighlights(pixels, threshold = EYE_QUALITY_THRESHOLDS.glarePixelThreshold) {
1785
+ function detectSpecularHighlights(pixels, relativeFactor = EYE_QUALITY_THRESHOLDS.glareRelativeFactor, meanBrightness) {
1778
1786
  const pixelCount = pixels.length / 4;
1779
1787
  if (pixelCount === 0) return 0;
1788
+ const mean = meanBrightness ?? analyzeEyeRegionBrightness(pixels);
1789
+ const threshold = mean * relativeFactor;
1780
1790
  let glareCount = 0;
1781
1791
  for (let i = 0; i < pixels.length; i += 4) {
1782
1792
  const lum = rgbaToLuminance(pixels[i], pixels[i + 1], pixels[i + 2]);
@@ -1799,7 +1809,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
1799
1809
  }
1800
1810
  const brightness = analyzeEyeRegionBrightness(pixels);
1801
1811
  const contrast = analyzeEyeRegionContrast(pixels, brightness);
1802
- const glareRatio = detectSpecularHighlights(pixels, thresholds.glarePixelThreshold);
1812
+ const glareRatio = detectSpecularHighlights(pixels, thresholds.glareRelativeFactor, brightness);
1803
1813
  const hasGlare = glareRatio > thresholds.maxGlareRatio;
1804
1814
  if (brightness < thresholds.minBrightness) {
1805
1815
  return {
@@ -1821,16 +1831,6 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
1821
1831
  message: "Eye region overexposed - reduce lighting"
1822
1832
  };
1823
1833
  }
1824
- if (hasGlare) {
1825
- return {
1826
- passed: false,
1827
- brightness,
1828
- contrast,
1829
- hasGlare,
1830
- glareRatio,
1831
- message: "Glare detected - adjust angle or remove glasses"
1832
- };
1833
- }
1834
1834
  if (contrast < thresholds.minContrast) {
1835
1835
  return {
1836
1836
  passed: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@moveris/shared",
3
- "version": "2.6.0",
3
+ "version": "2.7.0",
4
4
  "description": "Core business logic for Moveris Live SDK",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",