@moveris/shared 3.12.0 → 3.15.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/dist/index.d.mts CHANGED
@@ -59,6 +59,13 @@ interface FrameData {
59
59
  timestamp_ms: number;
60
60
  pixels: string;
61
61
  }
62
+ interface LiveCheckFrameData extends FrameData {
63
+ landmarks: {
64
+ x: number;
65
+ y: number;
66
+ z: number;
67
+ }[] | null;
68
+ }
62
69
  interface CropData {
63
70
  index: number;
64
71
  pixels: string;
@@ -79,6 +86,55 @@ interface FastCheckRequest {
79
86
  consumer?: ConsumerContext;
80
87
  } | null;
81
88
  }
89
+ interface LiveCheckRequest {
90
+ session_id: string;
91
+ model?: FastCheckModel;
92
+ source?: FrameSource;
93
+ frames: LiveCheckFrameData[];
94
+ frame_count?: number;
95
+ warnings?: string[];
96
+ device_intelligence?: DeviceIntelligence;
97
+ metadata?: {
98
+ consumer?: ConsumerContext;
99
+ } | null;
100
+ }
101
+ interface V2UploadFrameData extends FrameData {
102
+ landmarks?: {
103
+ x: number;
104
+ y: number;
105
+ z: number;
106
+ }[] | null;
107
+ }
108
+ interface V2UploadRequest {
109
+ session_id: string;
110
+ model?: FastCheckModel;
111
+ source?: FrameSource;
112
+ fps?: number;
113
+ frames: V2UploadFrameData[];
114
+ frame_count?: number;
115
+ warnings?: string[];
116
+ }
117
+ interface V2UploadResponse {
118
+ session_id: string;
119
+ frames_received: number;
120
+ frames_required: number;
121
+ is_complete: boolean;
122
+ ttl_seconds: number;
123
+ stored_durable: boolean;
124
+ }
125
+ interface V2FastCheckRequest {
126
+ session_id: string;
127
+ model?: FastCheckModel;
128
+ source?: FrameSource;
129
+ fps?: number;
130
+ frame_count?: number;
131
+ warnings?: string[];
132
+ device_intelligence?: DeviceIntelligence;
133
+ metadata?: {
134
+ consumer?: ConsumerContext;
135
+ } | null;
136
+ }
137
+ type V2LiveCheckRequest = V2FastCheckRequest;
82
138
  interface FastCheckCropsRequest {
83
139
  session_id: string;
84
140
  model?: FastCheckModel;
@@ -138,6 +194,7 @@ interface FastCheckResponse {
138
194
  warning: string | null;
139
195
  warnings?: string[] | null;
140
196
  error: string | null;
197
+ diagnostics?: Record<string, unknown> | null;
141
198
  }
142
199
  interface FastCheckStreamResponse {
143
200
  status: StreamingStatus;
@@ -225,6 +282,7 @@ interface LivenessResult {
225
282
  warnings?: string[];
226
283
  deprecation?: DeprecationInfo;
227
284
  clientTime?: number;
285
+ diagnostics?: Record<string, unknown> | null;
228
286
  }
229
287
  type LivenessState = 'idle' | 'capturing' | 'uploading' | 'processing' | 'complete' | 'error';
230
288
  interface LivenessConfig {
@@ -241,6 +299,11 @@ interface CapturedFrame {
241
299
  index: number;
242
300
  timestampMs: number;
243
301
  pixels: string;
302
+ landmarks?: {
303
+ x: number;
304
+ y: number;
305
+ z: number;
306
+ }[] | null;
244
307
  }
245
308
 
246
309
  type ModelType = FastCheckModel;
@@ -596,6 +659,9 @@ declare class LivenessApiError extends Error {
596
659
  constructor(message: string, code: string, statusCode: number, required?: number, received?: number);
597
660
  }
598
661
  declare function toFrameData(frames: CapturedFrame[]): FrameData[];
662
+ declare function toV2UploadFrameData(frames: CapturedFrame[], options?: {
663
+ withLandmarks?: boolean;
664
+ }): V2UploadFrameData[];
599
665
  declare function toHybridFrameData(frames: CapturedFrame[]): HybridFrameData[];
600
666
  declare function toLivenessResult(response: FastCheckResponse | VerifyResponse | HybridCheckResponse): LivenessResult;
601
667
  declare function toLivenessResultFromStream(response: FastCheckStreamResponse): LivenessResult;
@@ -640,6 +706,14 @@ declare class LivenessClient {
640
706
  source?: FrameSource;
641
707
  warnings?: string[];
642
708
  }): Promise<LivenessResult>;
709
+ liveCheck(frames: CapturedFrame[], options?: {
710
+ sessionId?: string;
711
+ model?: FastCheckModel;
712
+ modelVersion?: ModelVersion;
713
+ frameCount?: number;
714
+ source?: FrameSource;
715
+ warnings?: string[];
716
+ }): Promise<LivenessResult>;
643
717
  fastCheckCrops(crops: CropData[], options?: {
644
718
  sessionId?: string;
645
719
  model?: FastCheckModel;
@@ -701,6 +775,35 @@ declare class LivenessClient {
701
775
  }): Promise<LivenessResult>;
702
776
  getJobResult(jobId: string): Promise<JobStatusResponse>;
703
777
  waitForJobResult(jobId: string, timeout?: number): Promise<JobStatusResponse>;
778
+ v2Upload(frames: CapturedFrame[], options: {
779
+ sessionId: string;
780
+ model?: FastCheckModel;
781
+ modelVersion?: ModelVersion;
782
+ source?: FrameSource;
783
+ fps?: number;
784
+ frameCount?: number;
785
+ warnings?: string[];
786
+ withLandmarks?: boolean;
787
+ }): Promise<V2UploadResponse>;
788
+ v2FastCheck(options: {
789
+ sessionId: string;
790
+ model?: FastCheckModel;
791
+ modelVersion?: ModelVersion;
792
+ source?: FrameSource;
793
+ fps?: number;
794
+ frameCount?: number;
795
+ warnings?: string[];
796
+ }): Promise<LivenessResult>;
797
+ v2LiveCheck(options: {
798
+ sessionId: string;
799
+ model?: FastCheckModel;
800
+ modelVersion?: ModelVersion;
801
+ source?: FrameSource;
802
+ fps?: number;
803
+ frameCount?: number;
804
+ warnings?: string[];
805
+ }): Promise<LivenessResult>;
806
+ private runV2Check;
704
807
  }
705
808
 
706
809
  declare class FrameBuffer {
@@ -747,6 +850,7 @@ declare const API_PATHS: {
747
850
  readonly fastCheck: "/api/v1/fast-check";
748
851
  readonly fastCheckCrops: "/api/v1/fast-check-crops";
749
852
  readonly fastCheckStream: "/api/v1/fast-check-stream";
853
+ readonly liveCheck: "/api/v1/live-check";
750
854
  readonly verify: "/api/v1/verify";
751
855
  readonly hybridCheck: "/api/v1/hybrid-check";
752
856
  readonly hybrid50: "/api/v1/hybrid-50";
@@ -754,6 +858,9 @@ declare const API_PATHS: {
754
858
  readonly jobResult: "/api/v1/result";
755
859
  readonly queueStats: "/api/v1/queue/stats";
756
860
  readonly sessions: "/api/v1/sessions";
861
+ readonly v2Upload: "/api/v2/upload";
862
+ readonly v2FastCheck: "/api/v2/fast-check";
863
+ readonly v2LiveCheck: "/api/v2/live-check";
757
864
  };
758
865
  declare const RETRY_CONFIG: {
759
866
  readonly maxAttempts: 3;
@@ -968,4 +1075,4 @@ declare function collectDeviceIntelligence(opts?: {
968
1075
  platformVersion?: string;
969
1076
  }): Promise<DeviceIntelligence | null>;
970
1077
 
971
- 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, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CameraCapabilities, type CameraRequirements, type CameraValidationResult, type CaptureQualityState, type CapturedFrame, type ConsumerContext, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_CAMERA_REQUIREMENTS, 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, DYNAMIC_RANGE_WARNING_THRESHOLD, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, type DeviceIntelligence, type DeviceIntelligenceCamera, type DeviceIntelligenceGeo, type DeviceIntelligenceOverrides, type DynamicRangeAnalysis, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type ExtraMetadata, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CROP_FRAME_MARGIN, 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, 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_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_FACE_AREA_RATIO, 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 ModelVersion, 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, SHARED_SDK_PLATFORM, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeDynamicRange, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, linearRgbToLabL, retryWithBackoff, rgbaToGrayscale, sleep, srgbToLinear, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
1078
+ 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, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CameraCapabilities, type CameraRequirements, type CameraValidationResult, type CaptureQualityState, type CapturedFrame, type ConsumerContext, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_CAMERA_REQUIREMENTS, 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, DYNAMIC_RANGE_WARNING_THRESHOLD, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, type DeviceIntelligence, type DeviceIntelligenceCamera, type DeviceIntelligenceGeo, type DeviceIntelligenceOverrides, type DynamicRangeAnalysis, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type ExtraMetadata, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CROP_FRAME_MARGIN, 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, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, type LiveCheckFrameData, type LiveCheckRequest, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_FACE_AREA_RATIO, 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 ModelVersion, 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, SHARED_SDK_PLATFORM, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, type V2FastCheckRequest, type V2LiveCheckRequest, type V2UploadFrameData, type V2UploadRequest, type V2UploadResponse, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeDynamicRange, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, linearRgbToLabL, retryWithBackoff, rgbaToGrayscale, sleep, srgbToLinear, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, toV2UploadFrameData, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.d.ts CHANGED
@@ -59,6 +59,13 @@ interface FrameData {
59
59
  timestamp_ms: number;
60
60
  pixels: string;
61
61
  }
62
+ interface LiveCheckFrameData extends FrameData {
63
+ landmarks: {
64
+ x: number;
65
+ y: number;
66
+ z: number;
67
+ }[] | null;
68
+ }
62
69
  interface CropData {
63
70
  index: number;
64
71
  pixels: string;
@@ -79,6 +86,55 @@ interface FastCheckRequest {
79
86
  consumer?: ConsumerContext;
80
87
  } | null;
81
88
  }
89
+ interface LiveCheckRequest {
90
+ session_id: string;
91
+ model?: FastCheckModel;
92
+ source?: FrameSource;
93
+ frames: LiveCheckFrameData[];
94
+ frame_count?: number;
95
+ warnings?: string[];
96
+ device_intelligence?: DeviceIntelligence;
97
+ metadata?: {
98
+ consumer?: ConsumerContext;
99
+ } | null;
100
+ }
101
+ interface V2UploadFrameData extends FrameData {
102
+ landmarks?: {
103
+ x: number;
104
+ y: number;
105
+ z: number;
106
+ }[] | null;
107
+ }
108
+ interface V2UploadRequest {
109
+ session_id: string;
110
+ model?: FastCheckModel;
111
+ source?: FrameSource;
112
+ fps?: number;
113
+ frames: V2UploadFrameData[];
114
+ frame_count?: number;
115
+ warnings?: string[];
116
+ }
117
+ interface V2UploadResponse {
118
+ session_id: string;
119
+ frames_received: number;
120
+ frames_required: number;
121
+ is_complete: boolean;
122
+ ttl_seconds: number;
123
+ stored_durable: boolean;
124
+ }
125
+ interface V2FastCheckRequest {
126
+ session_id: string;
127
+ model?: FastCheckModel;
128
+ source?: FrameSource;
129
+ fps?: number;
130
+ frame_count?: number;
131
+ warnings?: string[];
132
+ device_intelligence?: DeviceIntelligence;
133
+ metadata?: {
134
+ consumer?: ConsumerContext;
135
+ } | null;
136
+ }
137
+ type V2LiveCheckRequest = V2FastCheckRequest;
82
138
  interface FastCheckCropsRequest {
83
139
  session_id: string;
84
140
  model?: FastCheckModel;
@@ -138,6 +194,7 @@ interface FastCheckResponse {
138
194
  warning: string | null;
139
195
  warnings?: string[] | null;
140
196
  error: string | null;
197
+ diagnostics?: Record<string, unknown> | null;
141
198
  }
142
199
  interface FastCheckStreamResponse {
143
200
  status: StreamingStatus;
@@ -225,6 +282,7 @@ interface LivenessResult {
225
282
  warnings?: string[];
226
283
  deprecation?: DeprecationInfo;
227
284
  clientTime?: number;
285
+ diagnostics?: Record<string, unknown> | null;
228
286
  }
229
287
  type LivenessState = 'idle' | 'capturing' | 'uploading' | 'processing' | 'complete' | 'error';
230
288
  interface LivenessConfig {
@@ -241,6 +299,11 @@ interface CapturedFrame {
241
299
  index: number;
242
300
  timestampMs: number;
243
301
  pixels: string;
302
+ landmarks?: {
303
+ x: number;
304
+ y: number;
305
+ z: number;
306
+ }[] | null;
244
307
  }
245
308
 
246
309
  type ModelType = FastCheckModel;
@@ -596,6 +659,9 @@ declare class LivenessApiError extends Error {
596
659
  constructor(message: string, code: string, statusCode: number, required?: number, received?: number);
597
660
  }
598
661
  declare function toFrameData(frames: CapturedFrame[]): FrameData[];
662
+ declare function toV2UploadFrameData(frames: CapturedFrame[], options?: {
663
+ withLandmarks?: boolean;
664
+ }): V2UploadFrameData[];
599
665
  declare function toHybridFrameData(frames: CapturedFrame[]): HybridFrameData[];
600
666
  declare function toLivenessResult(response: FastCheckResponse | VerifyResponse | HybridCheckResponse): LivenessResult;
601
667
  declare function toLivenessResultFromStream(response: FastCheckStreamResponse): LivenessResult;
@@ -640,6 +706,14 @@ declare class LivenessClient {
640
706
  source?: FrameSource;
641
707
  warnings?: string[];
642
708
  }): Promise<LivenessResult>;
709
+ liveCheck(frames: CapturedFrame[], options?: {
710
+ sessionId?: string;
711
+ model?: FastCheckModel;
712
+ modelVersion?: ModelVersion;
713
+ frameCount?: number;
714
+ source?: FrameSource;
715
+ warnings?: string[];
716
+ }): Promise<LivenessResult>;
643
717
  fastCheckCrops(crops: CropData[], options?: {
644
718
  sessionId?: string;
645
719
  model?: FastCheckModel;
@@ -701,6 +775,35 @@ declare class LivenessClient {
701
775
  }): Promise<LivenessResult>;
702
776
  getJobResult(jobId: string): Promise<JobStatusResponse>;
703
777
  waitForJobResult(jobId: string, timeout?: number): Promise<JobStatusResponse>;
778
+ v2Upload(frames: CapturedFrame[], options: {
779
+ sessionId: string;
780
+ model?: FastCheckModel;
781
+ modelVersion?: ModelVersion;
782
+ source?: FrameSource;
783
+ fps?: number;
784
+ frameCount?: number;
785
+ warnings?: string[];
786
+ withLandmarks?: boolean;
787
+ }): Promise<V2UploadResponse>;
788
+ v2FastCheck(options: {
789
+ sessionId: string;
790
+ model?: FastCheckModel;
791
+ modelVersion?: ModelVersion;
792
+ source?: FrameSource;
793
+ fps?: number;
794
+ frameCount?: number;
795
+ warnings?: string[];
796
+ }): Promise<LivenessResult>;
797
+ v2LiveCheck(options: {
798
+ sessionId: string;
799
+ model?: FastCheckModel;
800
+ modelVersion?: ModelVersion;
801
+ source?: FrameSource;
802
+ fps?: number;
803
+ frameCount?: number;
804
+ warnings?: string[];
805
+ }): Promise<LivenessResult>;
806
+ private runV2Check;
704
807
  }
705
808
 
706
809
  declare class FrameBuffer {
@@ -747,6 +850,7 @@ declare const API_PATHS: {
747
850
  readonly fastCheck: "/api/v1/fast-check";
748
851
  readonly fastCheckCrops: "/api/v1/fast-check-crops";
749
852
  readonly fastCheckStream: "/api/v1/fast-check-stream";
853
+ readonly liveCheck: "/api/v1/live-check";
750
854
  readonly verify: "/api/v1/verify";
751
855
  readonly hybridCheck: "/api/v1/hybrid-check";
752
856
  readonly hybrid50: "/api/v1/hybrid-50";
@@ -754,6 +858,9 @@ declare const API_PATHS: {
754
858
  readonly jobResult: "/api/v1/result";
755
859
  readonly queueStats: "/api/v1/queue/stats";
756
860
  readonly sessions: "/api/v1/sessions";
861
+ readonly v2Upload: "/api/v2/upload";
862
+ readonly v2FastCheck: "/api/v2/fast-check";
863
+ readonly v2LiveCheck: "/api/v2/live-check";
757
864
  };
758
865
  declare const RETRY_CONFIG: {
759
866
  readonly maxAttempts: 3;
@@ -968,4 +1075,4 @@ declare function collectDeviceIntelligence(opts?: {
968
1075
  platformVersion?: string;
969
1076
  }): Promise<DeviceIntelligence | null>;
970
1077
 
971
- 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, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CameraCapabilities, type CameraRequirements, type CameraValidationResult, type CaptureQualityState, type CapturedFrame, type ConsumerContext, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_CAMERA_REQUIREMENTS, 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, DYNAMIC_RANGE_WARNING_THRESHOLD, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, type DeviceIntelligence, type DeviceIntelligenceCamera, type DeviceIntelligenceGeo, type DeviceIntelligenceOverrides, type DynamicRangeAnalysis, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type ExtraMetadata, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CROP_FRAME_MARGIN, 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, 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_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_FACE_AREA_RATIO, 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 ModelVersion, 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, SHARED_SDK_PLATFORM, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeDynamicRange, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, linearRgbToLabL, retryWithBackoff, rgbaToGrayscale, sleep, srgbToLinear, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
1078
+ 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, CAMERA_ANGLE_HIGH_RATIO, CAMERA_ANGLE_LOW_RATIO, type CameraAngleResult, type CameraCapabilities, type CameraRequirements, type CameraValidationResult, type CaptureQualityState, type CapturedFrame, type ConsumerContext, type CropData, DEFAULT_BLUR_THRESHOLD, DEFAULT_CAMERA_REQUIREMENTS, 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, DYNAMIC_RANGE_WARNING_THRESHOLD, type DeprecationInfo, type DetectionResult, type DetectionSummary, type DetectorConfig, type DeviceIntelligence, type DeviceIntelligenceCamera, type DeviceIntelligenceGeo, type DeviceIntelligenceOverrides, type DynamicRangeAnalysis, ERROR_MESSAGES, ERROR_MESSAGES_ES, ES_LOCALE, EYE_LANDMARK_INDICES, EYE_QUALITY_THRESHOLDS, type ErrorResponse, type ExtraMetadata, type EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CROP_FRAME_MARGIN, 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, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, type LiveCheckFrameData, type LiveCheckRequest, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_FACE_AREA_RATIO, 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 ModelVersion, 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, SHARED_SDK_PLATFORM, type StabilizationProgress, type StabilizationResult, type StabilizerConfig, type StatusMessageKey, type StreamingStatus, TARGET_FACE_PERCENTAGE_IN_CROP, type V2FastCheckRequest, type V2LiveCheckRequest, type V2UploadFrameData, type V2UploadRequest, type V2UploadResponse, VALID_FRAME_COUNTS, type Verdict, type VerifyRequest, type VerifyResponse, type VideoFrameMetadata, analyzeBlur, analyzeDynamicRange, analyzeEyeRegionBrightness, analyzeEyeRegionContrast, analyzeLighting, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, getActiveModels, getApiErrorMessage, getCaptureQualityFeedback, getEyeRegionBounds, getFeedbackMessage, getMinFramesForModel, getOvalGuideState, getStatusMessage, hasEnoughFrames, isDeprecatedModel, isFaceCropFullyInFrame, isFaceFullyVisible, isFaceInOval, isRetryableError, linearRgbToLabL, retryWithBackoff, rgbaToGrayscale, sleep, srgbToLinear, toFrameData, toHybridFrameData, toLivenessResult, toLivenessResultFromStream, toV2UploadFrameData, validateApiKey, validateFaceLandmarks, validateFrameCount, validateFrameData, validateFrameIndex, validateTimestamp, validateUUID, validateUrl };
package/dist/index.js CHANGED
@@ -129,6 +129,7 @@ __export(index_exports, {
129
129
  toHybridFrameData: () => toHybridFrameData,
130
130
  toLivenessResult: () => toLivenessResult,
131
131
  toLivenessResultFromStream: () => toLivenessResultFromStream,
132
+ toV2UploadFrameData: () => toV2UploadFrameData,
132
133
  validateApiKey: () => validateApiKey,
133
134
  validateFaceLandmarks: () => validateFaceLandmarks,
134
135
  validateFrameCount: () => validateFrameCount,
@@ -153,13 +154,20 @@ var API_PATHS = {
153
154
  fastCheck: "/api/v1/fast-check",
154
155
  fastCheckCrops: "/api/v1/fast-check-crops",
155
156
  fastCheckStream: "/api/v1/fast-check-stream",
157
+ /** Live-check prototype (Phase 2): SDK-supplied landmarks per frame. */
158
+ liveCheck: "/api/v1/live-check",
156
159
  verify: "/api/v1/verify",
157
160
  hybridCheck: "/api/v1/hybrid-check",
158
161
  hybrid50: "/api/v1/hybrid-50",
159
162
  hybrid150: "/api/v1/hybrid-150",
160
163
  jobResult: "/api/v1/result",
161
164
  queueStats: "/api/v1/queue/stats",
162
- sessions: "/api/v1/sessions"
165
+ sessions: "/api/v1/sessions",
166
+ // v2 upload-first pipeline (MOV-1936). Separate from v1; frames are uploaded
167
+ // first and resolved server-side by session_id at check time.
168
+ v2Upload: "/api/v2/upload",
169
+ v2FastCheck: "/api/v2/fast-check",
170
+ v2LiveCheck: "/api/v2/live-check"
163
171
  };
164
172
  var RETRY_CONFIG = {
165
173
  maxAttempts: 3,
@@ -239,7 +247,7 @@ async function sleep(ms) {
239
247
  }
240
248
 
241
249
  // package.json
242
- var version = "3.12.0";
250
+ var version = "3.15.0";
243
251
 
244
252
  // src/utils/deviceIntelligence.ts
245
253
  var IPINFO_URL = "https://ipinfo.io/json";
@@ -298,6 +306,14 @@ var LivenessApiError = class extends Error {
298
306
  this.received = received;
299
307
  }
300
308
  };
309
+ function toLiveCheckFrameData(frames) {
310
+ return frames.map((frame) => ({
311
+ index: frame.index,
312
+ timestamp_ms: frame.timestampMs,
313
+ pixels: frame.pixels,
314
+ landmarks: frame.landmarks ? frame.landmarks.map((lm) => ({ x: lm.x, y: lm.y, z: lm.z })) : null
315
+ }));
316
+ }
301
317
  function toFrameData(frames) {
302
318
  return frames.map((frame) => ({
303
319
  index: frame.index,
@@ -305,6 +321,16 @@ function toFrameData(frames) {
305
321
  pixels: frame.pixels
306
322
  }));
307
323
  }
324
+ function toV2UploadFrameData(frames, options = {}) {
325
+ return frames.map((frame) => ({
326
+ index: frame.index,
327
+ timestamp_ms: frame.timestampMs,
328
+ pixels: frame.pixels,
329
+ ...options.withLandmarks ? {
330
+ landmarks: frame.landmarks ? frame.landmarks.map((lm) => ({ x: lm.x, y: lm.y, z: lm.z })) : null
331
+ } : {}
332
+ }));
333
+ }
308
334
  function toHybridFrameData(frames) {
309
335
  return frames.map((frame) => ({
310
336
  timestamp_ms: frame.timestampMs,
@@ -333,7 +359,10 @@ function toLivenessResult(response) {
333
359
  sessionId: response.session_id,
334
360
  processingMs: response.processing_ms,
335
361
  framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0,
336
- warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0
362
+ warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0,
363
+ // Live-check prototype: surface the server diagnostics block so the
364
+ // demo can log it. Production fast-check leaves this off the wire.
365
+ ..."diagnostics" in response && response.diagnostics != null ? { diagnostics: response.diagnostics } : {}
337
366
  };
338
367
  }
339
368
  function toLivenessResultFromStream(response) {
@@ -453,15 +482,16 @@ var LivenessClient = class _LivenessClient {
453
482
  const url = `${this.baseUrl}${path}`;
454
483
  const controller = new AbortController();
455
484
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
485
+ const mergedHeaders = {
486
+ "Content-Type": "application/json",
487
+ [AUTH_CONFIG.apiKeyHeader]: this.apiKey,
488
+ ...options.headers
489
+ };
456
490
  try {
457
491
  const response = await this.fetchFn(url, {
458
492
  ...options,
459
493
  signal: controller.signal,
460
- headers: {
461
- "Content-Type": "application/json",
462
- [AUTH_CONFIG.apiKeyHeader]: this.apiKey,
463
- ...options.headers
464
- }
494
+ headers: mergedHeaders
465
495
  });
466
496
  clearTimeout(timeoutId);
467
497
  if (!response.ok) {
@@ -704,6 +734,42 @@ var LivenessClient = class _LivenessClient {
704
734
  }
705
735
  return result;
706
736
  }
737
+ /**
738
+ * Live-check prototype (Phase 2): same payload shape as ``fastCheck``
739
+ * plus the MediaPipe Face Mesh landmarks the SDK already computed for
740
+ * each frame. The server uses those landmarks to skip its own
741
+ * MediaPipe Face Detection + Face Mesh calls — typically a 5–15s
742
+ * server-side win on V3.1 models.
743
+ *
744
+ * Required: every frame must include `landmarks` (a 468-entry array
745
+ * of `{x, y, z}` from MediaPipe Face Mesh). Frames whose `landmarks`
746
+ * is `null` flow through cleanly and are dropped server-side.
747
+ */
748
+ async liveCheck(frames, options = {}) {
749
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
750
+ const di = await this.getDeviceIntelligence();
751
+ const request = {
752
+ session_id: options.sessionId ?? generateSessionId(),
753
+ model: options.model ?? "10",
754
+ source: options.source ?? "live",
755
+ frames: toLiveCheckFrameData(frames),
756
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
757
+ ...options.warnings?.length ? { warnings: options.warnings } : {},
758
+ ...di ? { device_intelligence: di } : {},
759
+ ...this.buildMetadata() ? { metadata: this.buildMetadata() } : {}
760
+ };
761
+ const { data: response, headers } = await this.requestWithRetryRaw(
762
+ API_PATHS.liveCheck,
763
+ {
764
+ method: "POST",
765
+ body: JSON.stringify(request),
766
+ headers: this.buildModelVersionHeaders(effectiveVersion)
767
+ }
768
+ );
769
+ const result = toLivenessResult(response);
770
+ result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
771
+ return result;
772
+ }
707
773
  /**
708
774
  * Perform fast liveness check with pre-cropped face images
709
775
  *
@@ -1007,6 +1073,103 @@ var LivenessClient = class _LivenessClient {
1007
1073
  `${API_PATHS.jobResult}/${jobId}/wait?timeout=${timeout}`
1008
1074
  );
1009
1075
  }
1076
+ // ===========================================================================
1077
+ // v2 Pipeline (MOV-1936): upload-first
1078
+ //
1079
+ // Two-phase flow, fully separate from the v1 endpoints above:
1080
+ // 1. v2Upload() — buffer frames server-side (call once or repeatedly).
1081
+ // 2. v2FastCheck() / v2LiveCheck() — run inference; NO frames in the body,
1082
+ // the server resolves them by session_id from the prior upload(s).
1083
+ // The check responses reuse the v1 FastCheckResponse shape, so the existing
1084
+ // `toLivenessResult` + deprecation-header handling applies unchanged.
1085
+ // ===========================================================================
1086
+ /**
1087
+ * Buffer a batch of frames for a session (POST /api/v2/upload).
1088
+ *
1089
+ * Inference is NOT run here — this only stores frames keyed by `session_id`.
1090
+ * May be called multiple times for the same session (e.g. chunked during
1091
+ * capture); the server accumulates and reports cumulative progress.
1092
+ *
1093
+ * Set `withLandmarks` for the live-check path so MediaPipe landmarks travel
1094
+ * with each frame; leave it off for the fast-check path.
1095
+ *
1096
+ * @param frames - Captured frames to buffer
1097
+ * @param options - Session, model, source and upload flags
1098
+ * @returns Upload progress (frames_received / frames_required / is_complete)
1099
+ */
1100
+ async v2Upload(frames, options) {
1101
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
1102
+ const request = {
1103
+ session_id: options.sessionId,
1104
+ model: options.model ?? "10",
1105
+ source: options.source ?? "live",
1106
+ frames: toV2UploadFrameData(frames, { withLandmarks: options.withLandmarks }),
1107
+ ...options.fps != null ? { fps: options.fps } : {},
1108
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
1109
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
1110
+ };
1111
+ return this.requestWithRetry(API_PATHS.v2Upload, {
1112
+ method: "POST",
1113
+ body: JSON.stringify(request),
1114
+ headers: this.buildModelVersionHeaders(effectiveVersion)
1115
+ });
1116
+ }
1117
+ /**
1118
+ * Run a fast-check against frames previously uploaded via {@link v2Upload}
1119
+ * (POST /api/v2/fast-check). The request carries NO frames — the server
1120
+ * resolves them by `session_id`.
1121
+ *
1122
+ * @param options - Session and request context
1123
+ * @returns Liveness result
1124
+ */
1125
+ async v2FastCheck(options) {
1126
+ return this.runV2Check(API_PATHS.v2FastCheck, options);
1127
+ }
1128
+ /**
1129
+ * Run a live-check against frames previously uploaded via {@link v2Upload}
1130
+ * with `withLandmarks: true` (POST /api/v2/live-check). The request carries
1131
+ * NO frames. The server requires a V3 model and surfaces the V3 `diagnostics`
1132
+ * block on the result.
1133
+ *
1134
+ * @param options - Session and request context
1135
+ * @returns Liveness result (includes `diagnostics`)
1136
+ */
1137
+ async v2LiveCheck(options) {
1138
+ return this.runV2Check(API_PATHS.v2LiveCheck, options);
1139
+ }
1140
+ /**
1141
+ * Shared body for the v2 fast-check / live-check requests (internal).
1142
+ * Both endpoints take the identical no-frames payload and response shape;
1143
+ * only the path differs.
1144
+ */
1145
+ async runV2Check(path, options) {
1146
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
1147
+ const di = await this.getDeviceIntelligence();
1148
+ const metadata = this.buildMetadata();
1149
+ const request = {
1150
+ session_id: options.sessionId,
1151
+ model: options.model ?? "10",
1152
+ source: options.source ?? "live",
1153
+ ...options.fps != null ? { fps: options.fps } : {},
1154
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
1155
+ ...options.warnings?.length ? { warnings: options.warnings } : {},
1156
+ ...di ? { device_intelligence: di } : {},
1157
+ ...metadata ? { metadata } : {}
1158
+ };
1159
+ const { data: response, headers } = await this.requestWithRetryRaw(path, {
1160
+ method: "POST",
1161
+ body: JSON.stringify(request),
1162
+ headers: this.buildModelVersionHeaders(effectiveVersion)
1163
+ });
1164
+ const result = toLivenessResult(response);
1165
+ result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
1166
+ if (result.deprecation?.deprecated) {
1167
+ console.warn(
1168
+ `[Moveris] Model "${result.deprecation.resolvedModel}" is deprecated.` + (result.deprecation.suggestedModel ? ` Migrate to "${result.deprecation.suggestedModel}".` : "") + (result.deprecation.sunsetDate ? ` Sunset date: ${result.deprecation.sunsetDate}.` : "")
1169
+ );
1170
+ }
1171
+ return result;
1172
+ }
1010
1173
  };
1011
1174
 
1012
1175
  // src/buffer/FrameBuffer.ts
@@ -2522,6 +2685,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
2522
2685
  toHybridFrameData,
2523
2686
  toLivenessResult,
2524
2687
  toLivenessResultFromStream,
2688
+ toV2UploadFrameData,
2525
2689
  validateApiKey,
2526
2690
  validateFaceLandmarks,
2527
2691
  validateFrameCount,
package/dist/index.mjs CHANGED
@@ -11,13 +11,20 @@ var API_PATHS = {
11
11
  fastCheck: "/api/v1/fast-check",
12
12
  fastCheckCrops: "/api/v1/fast-check-crops",
13
13
  fastCheckStream: "/api/v1/fast-check-stream",
14
+ /** Live-check prototype (Phase 2): SDK-supplied landmarks per frame. */
15
+ liveCheck: "/api/v1/live-check",
14
16
  verify: "/api/v1/verify",
15
17
  hybridCheck: "/api/v1/hybrid-check",
16
18
  hybrid50: "/api/v1/hybrid-50",
17
19
  hybrid150: "/api/v1/hybrid-150",
18
20
  jobResult: "/api/v1/result",
19
21
  queueStats: "/api/v1/queue/stats",
20
- sessions: "/api/v1/sessions"
22
+ sessions: "/api/v1/sessions",
23
+ // v2 upload-first pipeline (MOV-1936). Separate from v1; frames are uploaded
24
+ // first and resolved server-side by session_id at check time.
25
+ v2Upload: "/api/v2/upload",
26
+ v2FastCheck: "/api/v2/fast-check",
27
+ v2LiveCheck: "/api/v2/live-check"
21
28
  };
22
29
  var RETRY_CONFIG = {
23
30
  maxAttempts: 3,
@@ -97,7 +104,7 @@ async function sleep(ms) {
97
104
  }
98
105
 
99
106
  // package.json
100
- var version = "3.12.0";
107
+ var version = "3.15.0";
101
108
 
102
109
  // src/utils/deviceIntelligence.ts
103
110
  var IPINFO_URL = "https://ipinfo.io/json";
@@ -156,6 +163,14 @@ var LivenessApiError = class extends Error {
156
163
  this.received = received;
157
164
  }
158
165
  };
166
+ function toLiveCheckFrameData(frames) {
167
+ return frames.map((frame) => ({
168
+ index: frame.index,
169
+ timestamp_ms: frame.timestampMs,
170
+ pixels: frame.pixels,
171
+ landmarks: frame.landmarks ? frame.landmarks.map((lm) => ({ x: lm.x, y: lm.y, z: lm.z })) : null
172
+ }));
173
+ }
159
174
  function toFrameData(frames) {
160
175
  return frames.map((frame) => ({
161
176
  index: frame.index,
@@ -163,6 +178,16 @@ function toFrameData(frames) {
163
178
  pixels: frame.pixels
164
179
  }));
165
180
  }
181
+ function toV2UploadFrameData(frames, options = {}) {
182
+ return frames.map((frame) => ({
183
+ index: frame.index,
184
+ timestamp_ms: frame.timestampMs,
185
+ pixels: frame.pixels,
186
+ ...options.withLandmarks ? {
187
+ landmarks: frame.landmarks ? frame.landmarks.map((lm) => ({ x: lm.x, y: lm.y, z: lm.z })) : null
188
+ } : {}
189
+ }));
190
+ }
166
191
  function toHybridFrameData(frames) {
167
192
  return frames.map((frame) => ({
168
193
  timestamp_ms: frame.timestampMs,
@@ -191,7 +216,10 @@ function toLivenessResult(response) {
191
216
  sessionId: response.session_id,
192
217
  processingMs: response.processing_ms,
193
218
  framesProcessed: "frames_processed" in response ? response.frames_processed ?? 0 : 0,
194
- warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0
219
+ warnings: "warnings" in response && Array.isArray(response.warnings) ? response.warnings : void 0,
220
+ // Live-check prototype: surface the server diagnostics block so the
221
+ // demo can log it. Production fast-check leaves this off the wire.
222
+ ..."diagnostics" in response && response.diagnostics != null ? { diagnostics: response.diagnostics } : {}
195
223
  };
196
224
  }
197
225
  function toLivenessResultFromStream(response) {
@@ -311,15 +339,16 @@ var LivenessClient = class _LivenessClient {
311
339
  const url = `${this.baseUrl}${path}`;
312
340
  const controller = new AbortController();
313
341
  const timeoutId = setTimeout(() => controller.abort(), this.timeout);
342
+ const mergedHeaders = {
343
+ "Content-Type": "application/json",
344
+ [AUTH_CONFIG.apiKeyHeader]: this.apiKey,
345
+ ...options.headers
346
+ };
314
347
  try {
315
348
  const response = await this.fetchFn(url, {
316
349
  ...options,
317
350
  signal: controller.signal,
318
- headers: {
319
- "Content-Type": "application/json",
320
- [AUTH_CONFIG.apiKeyHeader]: this.apiKey,
321
- ...options.headers
322
- }
351
+ headers: mergedHeaders
323
352
  });
324
353
  clearTimeout(timeoutId);
325
354
  if (!response.ok) {
@@ -562,6 +591,42 @@ var LivenessClient = class _LivenessClient {
562
591
  }
563
592
  return result;
564
593
  }
594
+ /**
595
+ * Live-check prototype (Phase 2): same payload shape as ``fastCheck``
596
+ * plus the MediaPipe Face Mesh landmarks the SDK already computed for
597
+ * each frame. The server uses those landmarks to skip its own
598
+ * MediaPipe Face Detection + Face Mesh calls — typically a 5–15s
599
+ * server-side win on V3.1 models.
600
+ *
601
+ * Required: every frame must include `landmarks` (a 468-entry array
602
+ * of `{x, y, z}` from MediaPipe Face Mesh). Frames whose `landmarks`
603
+ * is `null` flow through cleanly and are dropped server-side.
604
+ */
605
+ async liveCheck(frames, options = {}) {
606
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
607
+ const di = await this.getDeviceIntelligence();
608
+ const request = {
609
+ session_id: options.sessionId ?? generateSessionId(),
610
+ model: options.model ?? "10",
611
+ source: options.source ?? "live",
612
+ frames: toLiveCheckFrameData(frames),
613
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
614
+ ...options.warnings?.length ? { warnings: options.warnings } : {},
615
+ ...di ? { device_intelligence: di } : {},
616
+ ...this.buildMetadata() ? { metadata: this.buildMetadata() } : {}
617
+ };
618
+ const { data: response, headers } = await this.requestWithRetryRaw(
619
+ API_PATHS.liveCheck,
620
+ {
621
+ method: "POST",
622
+ body: JSON.stringify(request),
623
+ headers: this.buildModelVersionHeaders(effectiveVersion)
624
+ }
625
+ );
626
+ const result = toLivenessResult(response);
627
+ result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
628
+ return result;
629
+ }
565
630
  /**
566
631
  * Perform fast liveness check with pre-cropped face images
567
632
  *
@@ -865,6 +930,103 @@ var LivenessClient = class _LivenessClient {
865
930
  `${API_PATHS.jobResult}/${jobId}/wait?timeout=${timeout}`
866
931
  );
867
932
  }
933
+ // ===========================================================================
934
+ // v2 Pipeline (MOV-1936): upload-first
935
+ //
936
+ // Two-phase flow, fully separate from the v1 endpoints above:
937
+ // 1. v2Upload() — buffer frames server-side (call once or repeatedly).
938
+ // 2. v2FastCheck() / v2LiveCheck() — run inference; NO frames in the body,
939
+ // the server resolves them by session_id from the prior upload(s).
940
+ // The check responses reuse the v1 FastCheckResponse shape, so the existing
941
+ // `toLivenessResult` + deprecation-header handling applies unchanged.
942
+ // ===========================================================================
943
+ /**
944
+ * Buffer a batch of frames for a session (POST /api/v2/upload).
945
+ *
946
+ * Inference is NOT run here — this only stores frames keyed by `session_id`.
947
+ * May be called multiple times for the same session (e.g. chunked during
948
+ * capture); the server accumulates and reports cumulative progress.
949
+ *
950
+ * Set `withLandmarks` for the live-check path so MediaPipe landmarks travel
951
+ * with each frame; leave it off for the fast-check path.
952
+ *
953
+ * @param frames - Captured frames to buffer
954
+ * @param options - Session, model, source and upload flags
955
+ * @returns Upload progress (frames_received / frames_required / is_complete)
956
+ */
957
+ async v2Upload(frames, options) {
958
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
959
+ const request = {
960
+ session_id: options.sessionId,
961
+ model: options.model ?? "10",
962
+ source: options.source ?? "live",
963
+ frames: toV2UploadFrameData(frames, { withLandmarks: options.withLandmarks }),
964
+ ...options.fps != null ? { fps: options.fps } : {},
965
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
966
+ ...options.warnings?.length ? { warnings: options.warnings } : {}
967
+ };
968
+ return this.requestWithRetry(API_PATHS.v2Upload, {
969
+ method: "POST",
970
+ body: JSON.stringify(request),
971
+ headers: this.buildModelVersionHeaders(effectiveVersion)
972
+ });
973
+ }
974
+ /**
975
+ * Run a fast-check against frames previously uploaded via {@link v2Upload}
976
+ * (POST /api/v2/fast-check). The request carries NO frames — the server
977
+ * resolves them by `session_id`.
978
+ *
979
+ * @param options - Session and request context
980
+ * @returns Liveness result
981
+ */
982
+ async v2FastCheck(options) {
983
+ return this.runV2Check(API_PATHS.v2FastCheck, options);
984
+ }
985
+ /**
986
+ * Run a live-check against frames previously uploaded via {@link v2Upload}
987
+ * with `withLandmarks: true` (POST /api/v2/live-check). The request carries
988
+ * NO frames. The server requires a V3 model and surfaces the V3 `diagnostics`
989
+ * block on the result.
990
+ *
991
+ * @param options - Session and request context
992
+ * @returns Liveness result (includes `diagnostics`)
993
+ */
994
+ async v2LiveCheck(options) {
995
+ return this.runV2Check(API_PATHS.v2LiveCheck, options);
996
+ }
997
+ /**
998
+ * Shared body for the v2 fast-check / live-check requests (internal).
999
+ * Both endpoints take the identical no-frames payload and response shape;
1000
+ * only the path differs.
1001
+ */
1002
+ async runV2Check(path, options) {
1003
+ const effectiveVersion = options.modelVersion ?? this.modelVersion;
1004
+ const di = await this.getDeviceIntelligence();
1005
+ const metadata = this.buildMetadata();
1006
+ const request = {
1007
+ session_id: options.sessionId,
1008
+ model: options.model ?? "10",
1009
+ source: options.source ?? "live",
1010
+ ...options.fps != null ? { fps: options.fps } : {},
1011
+ ...options.frameCount != null ? { frame_count: options.frameCount } : {},
1012
+ ...options.warnings?.length ? { warnings: options.warnings } : {},
1013
+ ...di ? { device_intelligence: di } : {},
1014
+ ...metadata ? { metadata } : {}
1015
+ };
1016
+ const { data: response, headers } = await this.requestWithRetryRaw(path, {
1017
+ method: "POST",
1018
+ body: JSON.stringify(request),
1019
+ headers: this.buildModelVersionHeaders(effectiveVersion)
1020
+ });
1021
+ const result = toLivenessResult(response);
1022
+ result.deprecation = _LivenessClient.parseDeprecationHeaders(headers);
1023
+ if (result.deprecation?.deprecated) {
1024
+ console.warn(
1025
+ `[Moveris] Model "${result.deprecation.resolvedModel}" is deprecated.` + (result.deprecation.suggestedModel ? ` Migrate to "${result.deprecation.suggestedModel}".` : "") + (result.deprecation.sunsetDate ? ` Sunset date: ${result.deprecation.sunsetDate}.` : "")
1026
+ );
1027
+ }
1028
+ return result;
1029
+ }
868
1030
  };
869
1031
 
870
1032
  // src/buffer/FrameBuffer.ts
@@ -2379,6 +2541,7 @@ export {
2379
2541
  toHybridFrameData,
2380
2542
  toLivenessResult,
2381
2543
  toLivenessResultFromStream,
2544
+ toV2UploadFrameData,
2382
2545
  validateApiKey,
2383
2546
  validateFaceLandmarks,
2384
2547
  validateFrameCount,
package/package.json CHANGED
@@ -1,7 +1,8 @@
1
1
  {
2
2
  "name": "@moveris/shared",
3
- "version": "3.12.0",
3
+ "version": "3.15.0",
4
4
  "description": "Core business logic for Moveris Live SDK",
5
+ "author": "Moveris - Jeyson Palacio, Arthur ITurres, Eric D. Brown",
5
6
  "main": "./dist/index.js",
6
7
  "module": "./dist/index.mjs",
7
8
  "types": "./dist/index.d.ts",
@@ -21,7 +22,6 @@
21
22
  "websocket",
22
23
  "sdk"
23
24
  ],
24
- "author": "Jeyson Palacio",
25
25
  "license": "MIT",
26
26
  "devDependencies": {
27
27
  "@types/jest": "^29.5.11",