@moveris/shared 3.15.0 → 3.16.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 +107 -1
- package/dist/index.d.ts +107 -1
- package/dist/index.js +172 -2
- package/dist/index.mjs +168 -2
- package/package.json +1 -1
package/dist/index.d.mts
CHANGED
|
@@ -97,6 +97,8 @@ interface LiveCheckRequest {
|
|
|
97
97
|
metadata?: {
|
|
98
98
|
consumer?: ConsumerContext;
|
|
99
99
|
} | null;
|
|
100
|
+
trace_id?: string;
|
|
101
|
+
forensic_client?: unknown;
|
|
100
102
|
}
|
|
101
103
|
interface V2UploadFrameData extends FrameData {
|
|
102
104
|
landmarks?: {
|
|
@@ -639,6 +641,59 @@ interface CameraValidationResult {
|
|
|
639
641
|
}
|
|
640
642
|
declare const DEFAULT_CAMERA_REQUIREMENTS: CameraRequirements;
|
|
641
643
|
|
|
644
|
+
declare const FORENSIC_SCHEMA_VERSION = "1.0";
|
|
645
|
+
type ForensicSource = 'webcam' | 'media';
|
|
646
|
+
interface ClientStage {
|
|
647
|
+
stage_id: 'capture' | 'landmarks' | 'encode' | 'transport';
|
|
648
|
+
layer: 'sdk' | 'wire';
|
|
649
|
+
ok: boolean;
|
|
650
|
+
metrics: Record<string, unknown>;
|
|
651
|
+
}
|
|
652
|
+
interface ClientFragment {
|
|
653
|
+
trace_id: string;
|
|
654
|
+
schema_version: string;
|
|
655
|
+
source: ForensicSource;
|
|
656
|
+
origin: {
|
|
657
|
+
sdk_version?: string;
|
|
658
|
+
demo_commit?: string;
|
|
659
|
+
video_path?: string;
|
|
660
|
+
};
|
|
661
|
+
target: {
|
|
662
|
+
environment?: string;
|
|
663
|
+
model?: string;
|
|
664
|
+
endpoint?: string;
|
|
665
|
+
};
|
|
666
|
+
stages: ClientStage[];
|
|
667
|
+
}
|
|
668
|
+
interface CaptureSummary {
|
|
669
|
+
framesCaptured: number;
|
|
670
|
+
alignmentMean?: number;
|
|
671
|
+
blurVarMean?: number;
|
|
672
|
+
brightnessMean?: number;
|
|
673
|
+
landmarksPresentPct?: number;
|
|
674
|
+
validationPassPct?: number;
|
|
675
|
+
rollMean?: number;
|
|
676
|
+
yawMean?: number;
|
|
677
|
+
pitchMean?: number;
|
|
678
|
+
encoding?: string;
|
|
679
|
+
width?: number;
|
|
680
|
+
height?: number;
|
|
681
|
+
bytesPerFrame?: number;
|
|
682
|
+
framesSent?: number;
|
|
683
|
+
requestBytes?: number;
|
|
684
|
+
sessionId?: string;
|
|
685
|
+
}
|
|
686
|
+
interface FragmentContext {
|
|
687
|
+
sdkVersion?: string;
|
|
688
|
+
demoCommit?: string;
|
|
689
|
+
videoPath?: string;
|
|
690
|
+
environment?: string;
|
|
691
|
+
model?: string;
|
|
692
|
+
endpoint?: string;
|
|
693
|
+
}
|
|
694
|
+
declare function generateTraceId(): string;
|
|
695
|
+
declare function buildClientFragment(traceId: string, source: ForensicSource, summary: CaptureSummary, ctx?: FragmentContext): ClientFragment;
|
|
696
|
+
|
|
642
697
|
interface LivenessClientConfig {
|
|
643
698
|
baseUrl?: string;
|
|
644
699
|
apiKey: string;
|
|
@@ -650,6 +705,7 @@ interface LivenessClientConfig {
|
|
|
650
705
|
consumer?: ConsumerContext;
|
|
651
706
|
trackClientTime?: boolean;
|
|
652
707
|
extraMetadata?: ExtraMetadata;
|
|
708
|
+
traceId?: string;
|
|
653
709
|
}
|
|
654
710
|
declare class LivenessApiError extends Error {
|
|
655
711
|
readonly code: string;
|
|
@@ -676,6 +732,7 @@ declare class LivenessClient {
|
|
|
676
732
|
private readonly consumer;
|
|
677
733
|
private readonly trackClientTime;
|
|
678
734
|
private readonly extraMetadata;
|
|
735
|
+
private readonly traceId;
|
|
679
736
|
private diCollected;
|
|
680
737
|
private diCollecting;
|
|
681
738
|
private diOverrides;
|
|
@@ -713,6 +770,8 @@ declare class LivenessClient {
|
|
|
713
770
|
frameCount?: number;
|
|
714
771
|
source?: FrameSource;
|
|
715
772
|
warnings?: string[];
|
|
773
|
+
traceId?: string;
|
|
774
|
+
forensic?: ClientFragment;
|
|
716
775
|
}): Promise<LivenessResult>;
|
|
717
776
|
fastCheckCrops(crops: CropData[], options?: {
|
|
718
777
|
sessionId?: string;
|
|
@@ -1075,4 +1134,51 @@ declare function collectDeviceIntelligence(opts?: {
|
|
|
1075
1134
|
platformVersion?: string;
|
|
1076
1135
|
}): Promise<DeviceIntelligence | null>;
|
|
1077
1136
|
|
|
1078
|
-
|
|
1137
|
+
interface RecorderFrame {
|
|
1138
|
+
pixels?: string;
|
|
1139
|
+
landmarks?: unknown[] | null;
|
|
1140
|
+
}
|
|
1141
|
+
interface RecorderQuality {
|
|
1142
|
+
alignment?: number;
|
|
1143
|
+
blurVariance?: number;
|
|
1144
|
+
brightness?: number;
|
|
1145
|
+
landmarksValid?: boolean;
|
|
1146
|
+
width?: number;
|
|
1147
|
+
height?: number;
|
|
1148
|
+
encoding?: string;
|
|
1149
|
+
}
|
|
1150
|
+
declare class ForensicRecorder {
|
|
1151
|
+
readonly traceId: string;
|
|
1152
|
+
private readonly source;
|
|
1153
|
+
private readonly ctx;
|
|
1154
|
+
private framesCaptured;
|
|
1155
|
+
private landmarksPresent;
|
|
1156
|
+
private landmarksValid;
|
|
1157
|
+
private qualityTicks;
|
|
1158
|
+
private bytesTotal;
|
|
1159
|
+
private encoding;
|
|
1160
|
+
private width;
|
|
1161
|
+
private height;
|
|
1162
|
+
private readonly alignment;
|
|
1163
|
+
private readonly blur;
|
|
1164
|
+
private readonly brightness;
|
|
1165
|
+
private framesSent;
|
|
1166
|
+
private requestBytes;
|
|
1167
|
+
private sessionId;
|
|
1168
|
+
constructor(opts?: {
|
|
1169
|
+
source?: ForensicSource;
|
|
1170
|
+
traceId?: string;
|
|
1171
|
+
ctx?: FragmentContext;
|
|
1172
|
+
});
|
|
1173
|
+
onFrame(frame: RecorderFrame): void;
|
|
1174
|
+
onQuality(q: RecorderQuality): void;
|
|
1175
|
+
setTransport(t: {
|
|
1176
|
+
framesSent?: number;
|
|
1177
|
+
requestBytes?: number;
|
|
1178
|
+
sessionId?: string;
|
|
1179
|
+
}): void;
|
|
1180
|
+
summary(): CaptureSummary;
|
|
1181
|
+
build(): ClientFragment;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
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 CaptureSummary, type CapturedFrame, type ClientFragment, type ClientStage, 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, FORENSIC_SCHEMA_VERSION, 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, ForensicRecorder, type ForensicSource, type FragmentContext, 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 RecorderFrame, type RecorderQuality, 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, buildClientFragment, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, generateTraceId, 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
|
@@ -97,6 +97,8 @@ interface LiveCheckRequest {
|
|
|
97
97
|
metadata?: {
|
|
98
98
|
consumer?: ConsumerContext;
|
|
99
99
|
} | null;
|
|
100
|
+
trace_id?: string;
|
|
101
|
+
forensic_client?: unknown;
|
|
100
102
|
}
|
|
101
103
|
interface V2UploadFrameData extends FrameData {
|
|
102
104
|
landmarks?: {
|
|
@@ -639,6 +641,59 @@ interface CameraValidationResult {
|
|
|
639
641
|
}
|
|
640
642
|
declare const DEFAULT_CAMERA_REQUIREMENTS: CameraRequirements;
|
|
641
643
|
|
|
644
|
+
declare const FORENSIC_SCHEMA_VERSION = "1.0";
|
|
645
|
+
type ForensicSource = 'webcam' | 'media';
|
|
646
|
+
interface ClientStage {
|
|
647
|
+
stage_id: 'capture' | 'landmarks' | 'encode' | 'transport';
|
|
648
|
+
layer: 'sdk' | 'wire';
|
|
649
|
+
ok: boolean;
|
|
650
|
+
metrics: Record<string, unknown>;
|
|
651
|
+
}
|
|
652
|
+
interface ClientFragment {
|
|
653
|
+
trace_id: string;
|
|
654
|
+
schema_version: string;
|
|
655
|
+
source: ForensicSource;
|
|
656
|
+
origin: {
|
|
657
|
+
sdk_version?: string;
|
|
658
|
+
demo_commit?: string;
|
|
659
|
+
video_path?: string;
|
|
660
|
+
};
|
|
661
|
+
target: {
|
|
662
|
+
environment?: string;
|
|
663
|
+
model?: string;
|
|
664
|
+
endpoint?: string;
|
|
665
|
+
};
|
|
666
|
+
stages: ClientStage[];
|
|
667
|
+
}
|
|
668
|
+
interface CaptureSummary {
|
|
669
|
+
framesCaptured: number;
|
|
670
|
+
alignmentMean?: number;
|
|
671
|
+
blurVarMean?: number;
|
|
672
|
+
brightnessMean?: number;
|
|
673
|
+
landmarksPresentPct?: number;
|
|
674
|
+
validationPassPct?: number;
|
|
675
|
+
rollMean?: number;
|
|
676
|
+
yawMean?: number;
|
|
677
|
+
pitchMean?: number;
|
|
678
|
+
encoding?: string;
|
|
679
|
+
width?: number;
|
|
680
|
+
height?: number;
|
|
681
|
+
bytesPerFrame?: number;
|
|
682
|
+
framesSent?: number;
|
|
683
|
+
requestBytes?: number;
|
|
684
|
+
sessionId?: string;
|
|
685
|
+
}
|
|
686
|
+
interface FragmentContext {
|
|
687
|
+
sdkVersion?: string;
|
|
688
|
+
demoCommit?: string;
|
|
689
|
+
videoPath?: string;
|
|
690
|
+
environment?: string;
|
|
691
|
+
model?: string;
|
|
692
|
+
endpoint?: string;
|
|
693
|
+
}
|
|
694
|
+
declare function generateTraceId(): string;
|
|
695
|
+
declare function buildClientFragment(traceId: string, source: ForensicSource, summary: CaptureSummary, ctx?: FragmentContext): ClientFragment;
|
|
696
|
+
|
|
642
697
|
interface LivenessClientConfig {
|
|
643
698
|
baseUrl?: string;
|
|
644
699
|
apiKey: string;
|
|
@@ -650,6 +705,7 @@ interface LivenessClientConfig {
|
|
|
650
705
|
consumer?: ConsumerContext;
|
|
651
706
|
trackClientTime?: boolean;
|
|
652
707
|
extraMetadata?: ExtraMetadata;
|
|
708
|
+
traceId?: string;
|
|
653
709
|
}
|
|
654
710
|
declare class LivenessApiError extends Error {
|
|
655
711
|
readonly code: string;
|
|
@@ -676,6 +732,7 @@ declare class LivenessClient {
|
|
|
676
732
|
private readonly consumer;
|
|
677
733
|
private readonly trackClientTime;
|
|
678
734
|
private readonly extraMetadata;
|
|
735
|
+
private readonly traceId;
|
|
679
736
|
private diCollected;
|
|
680
737
|
private diCollecting;
|
|
681
738
|
private diOverrides;
|
|
@@ -713,6 +770,8 @@ declare class LivenessClient {
|
|
|
713
770
|
frameCount?: number;
|
|
714
771
|
source?: FrameSource;
|
|
715
772
|
warnings?: string[];
|
|
773
|
+
traceId?: string;
|
|
774
|
+
forensic?: ClientFragment;
|
|
716
775
|
}): Promise<LivenessResult>;
|
|
717
776
|
fastCheckCrops(crops: CropData[], options?: {
|
|
718
777
|
sessionId?: string;
|
|
@@ -1075,4 +1134,51 @@ declare function collectDeviceIntelligence(opts?: {
|
|
|
1075
1134
|
platformVersion?: string;
|
|
1076
1135
|
}): Promise<DeviceIntelligence | null>;
|
|
1077
1136
|
|
|
1078
|
-
|
|
1137
|
+
interface RecorderFrame {
|
|
1138
|
+
pixels?: string;
|
|
1139
|
+
landmarks?: unknown[] | null;
|
|
1140
|
+
}
|
|
1141
|
+
interface RecorderQuality {
|
|
1142
|
+
alignment?: number;
|
|
1143
|
+
blurVariance?: number;
|
|
1144
|
+
brightness?: number;
|
|
1145
|
+
landmarksValid?: boolean;
|
|
1146
|
+
width?: number;
|
|
1147
|
+
height?: number;
|
|
1148
|
+
encoding?: string;
|
|
1149
|
+
}
|
|
1150
|
+
declare class ForensicRecorder {
|
|
1151
|
+
readonly traceId: string;
|
|
1152
|
+
private readonly source;
|
|
1153
|
+
private readonly ctx;
|
|
1154
|
+
private framesCaptured;
|
|
1155
|
+
private landmarksPresent;
|
|
1156
|
+
private landmarksValid;
|
|
1157
|
+
private qualityTicks;
|
|
1158
|
+
private bytesTotal;
|
|
1159
|
+
private encoding;
|
|
1160
|
+
private width;
|
|
1161
|
+
private height;
|
|
1162
|
+
private readonly alignment;
|
|
1163
|
+
private readonly blur;
|
|
1164
|
+
private readonly brightness;
|
|
1165
|
+
private framesSent;
|
|
1166
|
+
private requestBytes;
|
|
1167
|
+
private sessionId;
|
|
1168
|
+
constructor(opts?: {
|
|
1169
|
+
source?: ForensicSource;
|
|
1170
|
+
traceId?: string;
|
|
1171
|
+
ctx?: FragmentContext;
|
|
1172
|
+
});
|
|
1173
|
+
onFrame(frame: RecorderFrame): void;
|
|
1174
|
+
onQuality(q: RecorderQuality): void;
|
|
1175
|
+
setTransport(t: {
|
|
1176
|
+
framesSent?: number;
|
|
1177
|
+
requestBytes?: number;
|
|
1178
|
+
sessionId?: string;
|
|
1179
|
+
}): void;
|
|
1180
|
+
summary(): CaptureSummary;
|
|
1181
|
+
build(): ClientFragment;
|
|
1182
|
+
}
|
|
1183
|
+
|
|
1184
|
+
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 CaptureSummary, type CapturedFrame, type ClientFragment, type ClientStage, 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, FORENSIC_SCHEMA_VERSION, 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, ForensicRecorder, type ForensicSource, type FragmentContext, 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 RecorderFrame, type RecorderQuality, 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, buildClientFragment, calculateBrightness, calculateFaceAlignment, calculateFaceCropRegion, canCaptureFrame, checkEyeRegionQuality, checkFrameQuality, collectDeviceIntelligence, decodeBase64, detectCameraAngle, detectFaceRoll, detectFaceRollFromMatrix, detectSpecularHighlights, encodeBase64, generateSessionId, generateTraceId, 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
|
@@ -53,8 +53,10 @@ __export(index_exports, {
|
|
|
53
53
|
FACE_CROP_FRAME_MARGIN: () => FACE_CROP_FRAME_MARGIN,
|
|
54
54
|
FACE_CROP_OUTPUT_SIZE: () => FACE_CROP_OUTPUT_SIZE,
|
|
55
55
|
FEEDBACK_MESSAGES: () => FEEDBACK_MESSAGES,
|
|
56
|
+
FORENSIC_SCHEMA_VERSION: () => FORENSIC_SCHEMA_VERSION,
|
|
56
57
|
FRAME_BUFFER_CONFIG: () => FRAME_BUFFER_CONFIG,
|
|
57
58
|
FRAME_CONFIG: () => FRAME_CONFIG,
|
|
59
|
+
ForensicRecorder: () => ForensicRecorder,
|
|
58
60
|
FrameBuffer: () => FrameBuffer,
|
|
59
61
|
FrameQueue: () => FrameQueue,
|
|
60
62
|
GOOD_ALIGNMENT: () => GOOD_ALIGNMENT,
|
|
@@ -92,6 +94,7 @@ __export(index_exports, {
|
|
|
92
94
|
analyzeEyeRegionBrightness: () => analyzeEyeRegionBrightness,
|
|
93
95
|
analyzeEyeRegionContrast: () => analyzeEyeRegionContrast,
|
|
94
96
|
analyzeLighting: () => analyzeLighting,
|
|
97
|
+
buildClientFragment: () => buildClientFragment,
|
|
95
98
|
calculateBrightness: () => calculateBrightness,
|
|
96
99
|
calculateFaceAlignment: () => calculateFaceAlignment,
|
|
97
100
|
calculateFaceCropRegion: () => calculateFaceCropRegion,
|
|
@@ -106,6 +109,7 @@ __export(index_exports, {
|
|
|
106
109
|
detectSpecularHighlights: () => detectSpecularHighlights,
|
|
107
110
|
encodeBase64: () => encodeBase64,
|
|
108
111
|
generateSessionId: () => generateSessionId,
|
|
112
|
+
generateTraceId: () => generateTraceId,
|
|
109
113
|
getActiveModels: () => getActiveModels,
|
|
110
114
|
getApiErrorMessage: () => getApiErrorMessage,
|
|
111
115
|
getCaptureQualityFeedback: () => getCaptureQualityFeedback,
|
|
@@ -247,7 +251,7 @@ async function sleep(ms) {
|
|
|
247
251
|
}
|
|
248
252
|
|
|
249
253
|
// package.json
|
|
250
|
-
var version = "3.
|
|
254
|
+
var version = "3.16.0";
|
|
251
255
|
|
|
252
256
|
// src/utils/deviceIntelligence.ts
|
|
253
257
|
var IPINFO_URL = "https://ipinfo.io/json";
|
|
@@ -295,6 +299,85 @@ async function collectDeviceIntelligence(opts) {
|
|
|
295
299
|
}
|
|
296
300
|
}
|
|
297
301
|
|
|
302
|
+
// src/forensic/clientFragment.ts
|
|
303
|
+
var FORENSIC_SCHEMA_VERSION = "1.0";
|
|
304
|
+
function defined(obj) {
|
|
305
|
+
const out = {};
|
|
306
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
307
|
+
if (v !== void 0 && v !== null) out[k] = v;
|
|
308
|
+
}
|
|
309
|
+
return out;
|
|
310
|
+
}
|
|
311
|
+
function generateTraceId() {
|
|
312
|
+
const c = globalThis.crypto;
|
|
313
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
314
|
+
return "trace-" + Math.abs(hashString(String(Date.now()) + ":" + performanceNow())).toString(36);
|
|
315
|
+
}
|
|
316
|
+
function performanceNow() {
|
|
317
|
+
const p = globalThis.performance;
|
|
318
|
+
return p?.now ? p.now() : 0;
|
|
319
|
+
}
|
|
320
|
+
function hashString(s) {
|
|
321
|
+
let h = 0;
|
|
322
|
+
for (let i = 0; i < s.length; i++) h = Math.imul(31, h) + s.charCodeAt(i) | 0;
|
|
323
|
+
return h;
|
|
324
|
+
}
|
|
325
|
+
function buildClientFragment(traceId, source, summary, ctx = {}) {
|
|
326
|
+
const stages = [];
|
|
327
|
+
const capture = defined({
|
|
328
|
+
frames_captured: summary.framesCaptured,
|
|
329
|
+
alignment_mean: summary.alignmentMean,
|
|
330
|
+
blur_var_mean: summary.blurVarMean,
|
|
331
|
+
brightness_mean: summary.brightnessMean
|
|
332
|
+
});
|
|
333
|
+
if (Object.keys(capture).length) {
|
|
334
|
+
stages.push({ stage_id: "capture", layer: "sdk", ok: true, metrics: capture });
|
|
335
|
+
}
|
|
336
|
+
const landmarks = defined({
|
|
337
|
+
landmarks_present_pct: summary.landmarksPresentPct,
|
|
338
|
+
validation_pass_pct: summary.validationPassPct,
|
|
339
|
+
roll_mean: summary.rollMean,
|
|
340
|
+
yaw_mean: summary.yawMean,
|
|
341
|
+
pitch_mean: summary.pitchMean
|
|
342
|
+
});
|
|
343
|
+
if (Object.keys(landmarks).length) {
|
|
344
|
+
stages.push({ stage_id: "landmarks", layer: "sdk", ok: true, metrics: landmarks });
|
|
345
|
+
}
|
|
346
|
+
const encode = defined({
|
|
347
|
+
encoding: summary.encoding,
|
|
348
|
+
w: summary.width,
|
|
349
|
+
h: summary.height,
|
|
350
|
+
bytes_per_frame: summary.bytesPerFrame
|
|
351
|
+
});
|
|
352
|
+
if (Object.keys(encode).length) {
|
|
353
|
+
stages.push({ stage_id: "encode", layer: "sdk", ok: true, metrics: encode });
|
|
354
|
+
}
|
|
355
|
+
const transport = defined({
|
|
356
|
+
frames_sent: summary.framesSent,
|
|
357
|
+
request_bytes: summary.requestBytes,
|
|
358
|
+
session_id: summary.sessionId
|
|
359
|
+
});
|
|
360
|
+
if (Object.keys(transport).length) {
|
|
361
|
+
stages.push({ stage_id: "transport", layer: "wire", ok: true, metrics: transport });
|
|
362
|
+
}
|
|
363
|
+
return {
|
|
364
|
+
trace_id: traceId,
|
|
365
|
+
schema_version: FORENSIC_SCHEMA_VERSION,
|
|
366
|
+
source,
|
|
367
|
+
origin: defined({
|
|
368
|
+
sdk_version: ctx.sdkVersion,
|
|
369
|
+
demo_commit: ctx.demoCommit,
|
|
370
|
+
video_path: ctx.videoPath
|
|
371
|
+
}),
|
|
372
|
+
target: defined({
|
|
373
|
+
environment: ctx.environment,
|
|
374
|
+
model: ctx.model,
|
|
375
|
+
endpoint: ctx.endpoint
|
|
376
|
+
}),
|
|
377
|
+
stages
|
|
378
|
+
};
|
|
379
|
+
}
|
|
380
|
+
|
|
298
381
|
// src/client/LivenessClient.ts
|
|
299
382
|
var LivenessApiError = class extends Error {
|
|
300
383
|
constructor(message, code, statusCode, required, received) {
|
|
@@ -419,6 +502,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
419
502
|
this.consumer = config.consumer;
|
|
420
503
|
this.trackClientTime = config.trackClientTime ?? false;
|
|
421
504
|
this.extraMetadata = config.extraMetadata;
|
|
505
|
+
this.traceId = config.traceId;
|
|
422
506
|
}
|
|
423
507
|
/**
|
|
424
508
|
* Merge additional device intelligence overrides into the existing set.
|
|
@@ -748,11 +832,14 @@ var LivenessClient = class _LivenessClient {
|
|
|
748
832
|
async liveCheck(frames, options = {}) {
|
|
749
833
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
750
834
|
const di = await this.getDeviceIntelligence();
|
|
835
|
+
const traceId = options.forensic?.trace_id ?? options.traceId ?? this.traceId ?? generateTraceId();
|
|
751
836
|
const request = {
|
|
752
837
|
session_id: options.sessionId ?? generateSessionId(),
|
|
753
838
|
model: options.model ?? "10",
|
|
754
839
|
source: options.source ?? "live",
|
|
755
840
|
frames: toLiveCheckFrameData(frames),
|
|
841
|
+
trace_id: traceId,
|
|
842
|
+
...options.forensic ? { forensic_client: options.forensic } : {},
|
|
756
843
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
757
844
|
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
758
845
|
...di ? { device_intelligence: di } : {},
|
|
@@ -763,7 +850,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
763
850
|
{
|
|
764
851
|
method: "POST",
|
|
765
852
|
body: JSON.stringify(request),
|
|
766
|
-
headers: this.buildModelVersionHeaders(effectiveVersion)
|
|
853
|
+
headers: { ...this.buildModelVersionHeaders(effectiveVersion), "X-Trace-Id": traceId }
|
|
767
854
|
}
|
|
768
855
|
);
|
|
769
856
|
const result = toLivenessResult(response);
|
|
@@ -2574,6 +2661,85 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2574
2661
|
message: null
|
|
2575
2662
|
};
|
|
2576
2663
|
}
|
|
2664
|
+
|
|
2665
|
+
// src/forensic/recorder.ts
|
|
2666
|
+
var RunningMean = class {
|
|
2667
|
+
constructor() {
|
|
2668
|
+
this.sum = 0;
|
|
2669
|
+
this.n = 0;
|
|
2670
|
+
}
|
|
2671
|
+
add(v) {
|
|
2672
|
+
if (typeof v === "number" && !Number.isNaN(v)) {
|
|
2673
|
+
this.sum += v;
|
|
2674
|
+
this.n += 1;
|
|
2675
|
+
}
|
|
2676
|
+
}
|
|
2677
|
+
get value() {
|
|
2678
|
+
return this.n ? this.sum / this.n : void 0;
|
|
2679
|
+
}
|
|
2680
|
+
};
|
|
2681
|
+
var ForensicRecorder = class {
|
|
2682
|
+
constructor(opts = {}) {
|
|
2683
|
+
this.framesCaptured = 0;
|
|
2684
|
+
this.landmarksPresent = 0;
|
|
2685
|
+
this.landmarksValid = 0;
|
|
2686
|
+
this.qualityTicks = 0;
|
|
2687
|
+
this.bytesTotal = 0;
|
|
2688
|
+
this.alignment = new RunningMean();
|
|
2689
|
+
this.blur = new RunningMean();
|
|
2690
|
+
this.brightness = new RunningMean();
|
|
2691
|
+
this.source = opts.source ?? "webcam";
|
|
2692
|
+
this.traceId = opts.traceId ?? generateTraceId();
|
|
2693
|
+
this.ctx = opts.ctx ?? {};
|
|
2694
|
+
}
|
|
2695
|
+
/** Record one captured frame (counts, landmark presence, encoded size). */
|
|
2696
|
+
onFrame(frame) {
|
|
2697
|
+
this.framesCaptured += 1;
|
|
2698
|
+
if (frame.landmarks && frame.landmarks.length) this.landmarksPresent += 1;
|
|
2699
|
+
if (typeof frame.pixels === "string") this.bytesTotal += frame.pixels.length;
|
|
2700
|
+
}
|
|
2701
|
+
/** Record one quality update (alignment/blur/brightness/landmark validity). */
|
|
2702
|
+
onQuality(q) {
|
|
2703
|
+
this.qualityTicks += 1;
|
|
2704
|
+
this.alignment.add(q.alignment);
|
|
2705
|
+
this.blur.add(q.blurVariance);
|
|
2706
|
+
this.brightness.add(q.brightness);
|
|
2707
|
+
if (q.landmarksValid) this.landmarksValid += 1;
|
|
2708
|
+
if (q.encoding) this.encoding = q.encoding;
|
|
2709
|
+
if (q.width) this.width = q.width;
|
|
2710
|
+
if (q.height) this.height = q.height;
|
|
2711
|
+
}
|
|
2712
|
+
/** Record the transport leg once the request is built/sent. */
|
|
2713
|
+
setTransport(t) {
|
|
2714
|
+
this.framesSent = t.framesSent;
|
|
2715
|
+
this.requestBytes = t.requestBytes;
|
|
2716
|
+
this.sessionId = t.sessionId;
|
|
2717
|
+
}
|
|
2718
|
+
/** Summarise the session into the CaptureSummary the fragment builder expects. */
|
|
2719
|
+
summary() {
|
|
2720
|
+
return {
|
|
2721
|
+
framesCaptured: this.framesCaptured,
|
|
2722
|
+
alignmentMean: this.alignment.value,
|
|
2723
|
+
blurVarMean: this.blur.value,
|
|
2724
|
+
brightnessMean: this.brightness.value,
|
|
2725
|
+
landmarksPresentPct: this.framesCaptured ? this.landmarksPresent / this.framesCaptured : void 0,
|
|
2726
|
+
// validity is a fraction of QUALITY ticks, not frames — quality updates fire
|
|
2727
|
+
// more often than frames, so dividing by frames could exceed 1.0.
|
|
2728
|
+
validationPassPct: this.qualityTicks ? this.landmarksValid / this.qualityTicks : void 0,
|
|
2729
|
+
encoding: this.encoding,
|
|
2730
|
+
width: this.width,
|
|
2731
|
+
height: this.height,
|
|
2732
|
+
bytesPerFrame: this.framesCaptured && this.bytesTotal ? Math.round(this.bytesTotal / this.framesCaptured) : void 0,
|
|
2733
|
+
framesSent: this.framesSent ?? (this.framesCaptured || void 0),
|
|
2734
|
+
requestBytes: this.requestBytes,
|
|
2735
|
+
sessionId: this.sessionId
|
|
2736
|
+
};
|
|
2737
|
+
}
|
|
2738
|
+
/** Build the client fragment for this session. */
|
|
2739
|
+
build() {
|
|
2740
|
+
return buildClientFragment(this.traceId, this.source, this.summary(), this.ctx);
|
|
2741
|
+
}
|
|
2742
|
+
};
|
|
2577
2743
|
// Annotate the CommonJS export names for ESM import in node:
|
|
2578
2744
|
0 && (module.exports = {
|
|
2579
2745
|
ALIGNMENT_THRESHOLD_CAPTURE,
|
|
@@ -2609,8 +2775,10 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2609
2775
|
FACE_CROP_FRAME_MARGIN,
|
|
2610
2776
|
FACE_CROP_OUTPUT_SIZE,
|
|
2611
2777
|
FEEDBACK_MESSAGES,
|
|
2778
|
+
FORENSIC_SCHEMA_VERSION,
|
|
2612
2779
|
FRAME_BUFFER_CONFIG,
|
|
2613
2780
|
FRAME_CONFIG,
|
|
2781
|
+
ForensicRecorder,
|
|
2614
2782
|
FrameBuffer,
|
|
2615
2783
|
FrameQueue,
|
|
2616
2784
|
GOOD_ALIGNMENT,
|
|
@@ -2648,6 +2816,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2648
2816
|
analyzeEyeRegionBrightness,
|
|
2649
2817
|
analyzeEyeRegionContrast,
|
|
2650
2818
|
analyzeLighting,
|
|
2819
|
+
buildClientFragment,
|
|
2651
2820
|
calculateBrightness,
|
|
2652
2821
|
calculateFaceAlignment,
|
|
2653
2822
|
calculateFaceCropRegion,
|
|
@@ -2662,6 +2831,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2662
2831
|
detectSpecularHighlights,
|
|
2663
2832
|
encodeBase64,
|
|
2664
2833
|
generateSessionId,
|
|
2834
|
+
generateTraceId,
|
|
2665
2835
|
getActiveModels,
|
|
2666
2836
|
getApiErrorMessage,
|
|
2667
2837
|
getCaptureQualityFeedback,
|
package/dist/index.mjs
CHANGED
|
@@ -104,7 +104,7 @@ async function sleep(ms) {
|
|
|
104
104
|
}
|
|
105
105
|
|
|
106
106
|
// package.json
|
|
107
|
-
var version = "3.
|
|
107
|
+
var version = "3.16.0";
|
|
108
108
|
|
|
109
109
|
// src/utils/deviceIntelligence.ts
|
|
110
110
|
var IPINFO_URL = "https://ipinfo.io/json";
|
|
@@ -152,6 +152,85 @@ async function collectDeviceIntelligence(opts) {
|
|
|
152
152
|
}
|
|
153
153
|
}
|
|
154
154
|
|
|
155
|
+
// src/forensic/clientFragment.ts
|
|
156
|
+
var FORENSIC_SCHEMA_VERSION = "1.0";
|
|
157
|
+
function defined(obj) {
|
|
158
|
+
const out = {};
|
|
159
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
160
|
+
if (v !== void 0 && v !== null) out[k] = v;
|
|
161
|
+
}
|
|
162
|
+
return out;
|
|
163
|
+
}
|
|
164
|
+
function generateTraceId() {
|
|
165
|
+
const c = globalThis.crypto;
|
|
166
|
+
if (c?.randomUUID) return c.randomUUID();
|
|
167
|
+
return "trace-" + Math.abs(hashString(String(Date.now()) + ":" + performanceNow())).toString(36);
|
|
168
|
+
}
|
|
169
|
+
function performanceNow() {
|
|
170
|
+
const p = globalThis.performance;
|
|
171
|
+
return p?.now ? p.now() : 0;
|
|
172
|
+
}
|
|
173
|
+
function hashString(s) {
|
|
174
|
+
let h = 0;
|
|
175
|
+
for (let i = 0; i < s.length; i++) h = Math.imul(31, h) + s.charCodeAt(i) | 0;
|
|
176
|
+
return h;
|
|
177
|
+
}
|
|
178
|
+
function buildClientFragment(traceId, source, summary, ctx = {}) {
|
|
179
|
+
const stages = [];
|
|
180
|
+
const capture = defined({
|
|
181
|
+
frames_captured: summary.framesCaptured,
|
|
182
|
+
alignment_mean: summary.alignmentMean,
|
|
183
|
+
blur_var_mean: summary.blurVarMean,
|
|
184
|
+
brightness_mean: summary.brightnessMean
|
|
185
|
+
});
|
|
186
|
+
if (Object.keys(capture).length) {
|
|
187
|
+
stages.push({ stage_id: "capture", layer: "sdk", ok: true, metrics: capture });
|
|
188
|
+
}
|
|
189
|
+
const landmarks = defined({
|
|
190
|
+
landmarks_present_pct: summary.landmarksPresentPct,
|
|
191
|
+
validation_pass_pct: summary.validationPassPct,
|
|
192
|
+
roll_mean: summary.rollMean,
|
|
193
|
+
yaw_mean: summary.yawMean,
|
|
194
|
+
pitch_mean: summary.pitchMean
|
|
195
|
+
});
|
|
196
|
+
if (Object.keys(landmarks).length) {
|
|
197
|
+
stages.push({ stage_id: "landmarks", layer: "sdk", ok: true, metrics: landmarks });
|
|
198
|
+
}
|
|
199
|
+
const encode = defined({
|
|
200
|
+
encoding: summary.encoding,
|
|
201
|
+
w: summary.width,
|
|
202
|
+
h: summary.height,
|
|
203
|
+
bytes_per_frame: summary.bytesPerFrame
|
|
204
|
+
});
|
|
205
|
+
if (Object.keys(encode).length) {
|
|
206
|
+
stages.push({ stage_id: "encode", layer: "sdk", ok: true, metrics: encode });
|
|
207
|
+
}
|
|
208
|
+
const transport = defined({
|
|
209
|
+
frames_sent: summary.framesSent,
|
|
210
|
+
request_bytes: summary.requestBytes,
|
|
211
|
+
session_id: summary.sessionId
|
|
212
|
+
});
|
|
213
|
+
if (Object.keys(transport).length) {
|
|
214
|
+
stages.push({ stage_id: "transport", layer: "wire", ok: true, metrics: transport });
|
|
215
|
+
}
|
|
216
|
+
return {
|
|
217
|
+
trace_id: traceId,
|
|
218
|
+
schema_version: FORENSIC_SCHEMA_VERSION,
|
|
219
|
+
source,
|
|
220
|
+
origin: defined({
|
|
221
|
+
sdk_version: ctx.sdkVersion,
|
|
222
|
+
demo_commit: ctx.demoCommit,
|
|
223
|
+
video_path: ctx.videoPath
|
|
224
|
+
}),
|
|
225
|
+
target: defined({
|
|
226
|
+
environment: ctx.environment,
|
|
227
|
+
model: ctx.model,
|
|
228
|
+
endpoint: ctx.endpoint
|
|
229
|
+
}),
|
|
230
|
+
stages
|
|
231
|
+
};
|
|
232
|
+
}
|
|
233
|
+
|
|
155
234
|
// src/client/LivenessClient.ts
|
|
156
235
|
var LivenessApiError = class extends Error {
|
|
157
236
|
constructor(message, code, statusCode, required, received) {
|
|
@@ -276,6 +355,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
276
355
|
this.consumer = config.consumer;
|
|
277
356
|
this.trackClientTime = config.trackClientTime ?? false;
|
|
278
357
|
this.extraMetadata = config.extraMetadata;
|
|
358
|
+
this.traceId = config.traceId;
|
|
279
359
|
}
|
|
280
360
|
/**
|
|
281
361
|
* Merge additional device intelligence overrides into the existing set.
|
|
@@ -605,11 +685,14 @@ var LivenessClient = class _LivenessClient {
|
|
|
605
685
|
async liveCheck(frames, options = {}) {
|
|
606
686
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
607
687
|
const di = await this.getDeviceIntelligence();
|
|
688
|
+
const traceId = options.forensic?.trace_id ?? options.traceId ?? this.traceId ?? generateTraceId();
|
|
608
689
|
const request = {
|
|
609
690
|
session_id: options.sessionId ?? generateSessionId(),
|
|
610
691
|
model: options.model ?? "10",
|
|
611
692
|
source: options.source ?? "live",
|
|
612
693
|
frames: toLiveCheckFrameData(frames),
|
|
694
|
+
trace_id: traceId,
|
|
695
|
+
...options.forensic ? { forensic_client: options.forensic } : {},
|
|
613
696
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
614
697
|
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
615
698
|
...di ? { device_intelligence: di } : {},
|
|
@@ -620,7 +703,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
620
703
|
{
|
|
621
704
|
method: "POST",
|
|
622
705
|
body: JSON.stringify(request),
|
|
623
|
-
headers: this.buildModelVersionHeaders(effectiveVersion)
|
|
706
|
+
headers: { ...this.buildModelVersionHeaders(effectiveVersion), "X-Trace-Id": traceId }
|
|
624
707
|
}
|
|
625
708
|
);
|
|
626
709
|
const result = toLivenessResult(response);
|
|
@@ -2431,6 +2514,85 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2431
2514
|
message: null
|
|
2432
2515
|
};
|
|
2433
2516
|
}
|
|
2517
|
+
|
|
2518
|
+
// src/forensic/recorder.ts
|
|
2519
|
+
var RunningMean = class {
|
|
2520
|
+
constructor() {
|
|
2521
|
+
this.sum = 0;
|
|
2522
|
+
this.n = 0;
|
|
2523
|
+
}
|
|
2524
|
+
add(v) {
|
|
2525
|
+
if (typeof v === "number" && !Number.isNaN(v)) {
|
|
2526
|
+
this.sum += v;
|
|
2527
|
+
this.n += 1;
|
|
2528
|
+
}
|
|
2529
|
+
}
|
|
2530
|
+
get value() {
|
|
2531
|
+
return this.n ? this.sum / this.n : void 0;
|
|
2532
|
+
}
|
|
2533
|
+
};
|
|
2534
|
+
var ForensicRecorder = class {
|
|
2535
|
+
constructor(opts = {}) {
|
|
2536
|
+
this.framesCaptured = 0;
|
|
2537
|
+
this.landmarksPresent = 0;
|
|
2538
|
+
this.landmarksValid = 0;
|
|
2539
|
+
this.qualityTicks = 0;
|
|
2540
|
+
this.bytesTotal = 0;
|
|
2541
|
+
this.alignment = new RunningMean();
|
|
2542
|
+
this.blur = new RunningMean();
|
|
2543
|
+
this.brightness = new RunningMean();
|
|
2544
|
+
this.source = opts.source ?? "webcam";
|
|
2545
|
+
this.traceId = opts.traceId ?? generateTraceId();
|
|
2546
|
+
this.ctx = opts.ctx ?? {};
|
|
2547
|
+
}
|
|
2548
|
+
/** Record one captured frame (counts, landmark presence, encoded size). */
|
|
2549
|
+
onFrame(frame) {
|
|
2550
|
+
this.framesCaptured += 1;
|
|
2551
|
+
if (frame.landmarks && frame.landmarks.length) this.landmarksPresent += 1;
|
|
2552
|
+
if (typeof frame.pixels === "string") this.bytesTotal += frame.pixels.length;
|
|
2553
|
+
}
|
|
2554
|
+
/** Record one quality update (alignment/blur/brightness/landmark validity). */
|
|
2555
|
+
onQuality(q) {
|
|
2556
|
+
this.qualityTicks += 1;
|
|
2557
|
+
this.alignment.add(q.alignment);
|
|
2558
|
+
this.blur.add(q.blurVariance);
|
|
2559
|
+
this.brightness.add(q.brightness);
|
|
2560
|
+
if (q.landmarksValid) this.landmarksValid += 1;
|
|
2561
|
+
if (q.encoding) this.encoding = q.encoding;
|
|
2562
|
+
if (q.width) this.width = q.width;
|
|
2563
|
+
if (q.height) this.height = q.height;
|
|
2564
|
+
}
|
|
2565
|
+
/** Record the transport leg once the request is built/sent. */
|
|
2566
|
+
setTransport(t) {
|
|
2567
|
+
this.framesSent = t.framesSent;
|
|
2568
|
+
this.requestBytes = t.requestBytes;
|
|
2569
|
+
this.sessionId = t.sessionId;
|
|
2570
|
+
}
|
|
2571
|
+
/** Summarise the session into the CaptureSummary the fragment builder expects. */
|
|
2572
|
+
summary() {
|
|
2573
|
+
return {
|
|
2574
|
+
framesCaptured: this.framesCaptured,
|
|
2575
|
+
alignmentMean: this.alignment.value,
|
|
2576
|
+
blurVarMean: this.blur.value,
|
|
2577
|
+
brightnessMean: this.brightness.value,
|
|
2578
|
+
landmarksPresentPct: this.framesCaptured ? this.landmarksPresent / this.framesCaptured : void 0,
|
|
2579
|
+
// validity is a fraction of QUALITY ticks, not frames — quality updates fire
|
|
2580
|
+
// more often than frames, so dividing by frames could exceed 1.0.
|
|
2581
|
+
validationPassPct: this.qualityTicks ? this.landmarksValid / this.qualityTicks : void 0,
|
|
2582
|
+
encoding: this.encoding,
|
|
2583
|
+
width: this.width,
|
|
2584
|
+
height: this.height,
|
|
2585
|
+
bytesPerFrame: this.framesCaptured && this.bytesTotal ? Math.round(this.bytesTotal / this.framesCaptured) : void 0,
|
|
2586
|
+
framesSent: this.framesSent ?? (this.framesCaptured || void 0),
|
|
2587
|
+
requestBytes: this.requestBytes,
|
|
2588
|
+
sessionId: this.sessionId
|
|
2589
|
+
};
|
|
2590
|
+
}
|
|
2591
|
+
/** Build the client fragment for this session. */
|
|
2592
|
+
build() {
|
|
2593
|
+
return buildClientFragment(this.traceId, this.source, this.summary(), this.ctx);
|
|
2594
|
+
}
|
|
2595
|
+
};
|
|
2434
2596
|
export {
|
|
2435
2597
|
ALIGNMENT_THRESHOLD_CAPTURE,
|
|
2436
2598
|
ALIGNMENT_THRESHOLD_GOOD,
|
|
@@ -2465,8 +2627,10 @@ export {
|
|
|
2465
2627
|
FACE_CROP_FRAME_MARGIN,
|
|
2466
2628
|
FACE_CROP_OUTPUT_SIZE,
|
|
2467
2629
|
FEEDBACK_MESSAGES,
|
|
2630
|
+
FORENSIC_SCHEMA_VERSION,
|
|
2468
2631
|
FRAME_BUFFER_CONFIG,
|
|
2469
2632
|
FRAME_CONFIG,
|
|
2633
|
+
ForensicRecorder,
|
|
2470
2634
|
FrameBuffer,
|
|
2471
2635
|
FrameQueue,
|
|
2472
2636
|
GOOD_ALIGNMENT,
|
|
@@ -2504,6 +2668,7 @@ export {
|
|
|
2504
2668
|
analyzeEyeRegionBrightness,
|
|
2505
2669
|
analyzeEyeRegionContrast,
|
|
2506
2670
|
analyzeLighting,
|
|
2671
|
+
buildClientFragment,
|
|
2507
2672
|
calculateBrightness,
|
|
2508
2673
|
calculateFaceAlignment,
|
|
2509
2674
|
calculateFaceCropRegion,
|
|
@@ -2518,6 +2683,7 @@ export {
|
|
|
2518
2683
|
detectSpecularHighlights,
|
|
2519
2684
|
encodeBase64,
|
|
2520
2685
|
generateSessionId,
|
|
2686
|
+
generateTraceId,
|
|
2521
2687
|
getActiveModels,
|
|
2522
2688
|
getApiErrorMessage,
|
|
2523
2689
|
getCaptureQualityFeedback,
|