@moveris/shared 3.6.2 → 3.8.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +110 -8
- package/dist/index.d.mts +44 -1
- package/dist/index.d.ts +44 -1
- package/dist/index.js +111 -6
- package/dist/index.mjs +109 -6
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -47,14 +47,15 @@ The main client for interacting with the Moveris Liveness API.
|
|
|
47
47
|
const client = new LivenessClient(config: LivenessClientConfig);
|
|
48
48
|
```
|
|
49
49
|
|
|
50
|
-
| Option
|
|
51
|
-
|
|
|
52
|
-
| `apiKey`
|
|
53
|
-
| `baseUrl`
|
|
54
|
-
| `modelVersion`
|
|
55
|
-
| `timeout`
|
|
56
|
-
| `enableRetry`
|
|
57
|
-
| `customFetch`
|
|
50
|
+
| Option | Type | Default | Description |
|
|
51
|
+
| ----------------------------- | ----------------------------- | --------------------------- | ------------------------------------------------------------------------------------------------ |
|
|
52
|
+
| `apiKey` | `string` | **required** | Your Moveris API key |
|
|
53
|
+
| `baseUrl` | `string` | `'https://api.moveris.com'` | API base URL |
|
|
54
|
+
| `modelVersion` | `ModelVersion` | - | Model version alias for `X-Model-Version` header (e.g. `'latest'`) |
|
|
55
|
+
| `timeout` | `number` | `30000` | Request timeout in milliseconds |
|
|
56
|
+
| `enableRetry` | `boolean` | `true` | Enable automatic retry with exponential backoff |
|
|
57
|
+
| `customFetch` | `typeof fetch` | `fetch` | Custom fetch implementation (for React Native) |
|
|
58
|
+
| `deviceIntelligenceOverrides` | `DeviceIntelligenceOverrides` | - | Static overrides merged into every `device_intelligence` payload (e.g. `{ vpn_detected: true }`) |
|
|
58
59
|
|
|
59
60
|
#### Methods
|
|
60
61
|
|
|
@@ -151,6 +152,17 @@ const result = await client.hybrid50(frames, { fps: 30 });
|
|
|
151
152
|
const result = await client.hybrid150(frames, { fps: 30 });
|
|
152
153
|
```
|
|
153
154
|
|
|
155
|
+
##### `updateDeviceIntelligenceOverrides(overrides)`
|
|
156
|
+
|
|
157
|
+
Merge additional fields into the cached device intelligence payload. Call this after construction to inject data only available at runtime (e.g. camera specs, VPN detection results). Merges shallowly — later calls are merged on top of earlier ones.
|
|
158
|
+
|
|
159
|
+
```typescript
|
|
160
|
+
client.updateDeviceIntelligenceOverrides({
|
|
161
|
+
camera: { device_name: 'FaceTime HD Camera', resolution: '1280x720' },
|
|
162
|
+
});
|
|
163
|
+
client.updateDeviceIntelligenceOverrides({ vpn_detected: true });
|
|
164
|
+
```
|
|
165
|
+
|
|
154
166
|
##### `health()`
|
|
155
167
|
|
|
156
168
|
Check API health status.
|
|
@@ -726,6 +738,91 @@ const active = getActiveModels();
|
|
|
726
738
|
|
|
727
739
|
---
|
|
728
740
|
|
|
741
|
+
## Device Intelligence
|
|
742
|
+
|
|
743
|
+
The SDK automatically collects device metadata and attaches it to every API request as `device_intelligence`. Collection happens inside `LivenessClient` — no extra work required for standard consumers.
|
|
744
|
+
|
|
745
|
+
### `collectDeviceIntelligence(opts?)`
|
|
746
|
+
|
|
747
|
+
Collect device metadata manually. Useful for Approach B consumers (custom UI + raw `fetch()`) who bypass `LivenessClient`.
|
|
748
|
+
|
|
749
|
+
```typescript
|
|
750
|
+
import { collectDeviceIntelligence } from '@moveris/shared';
|
|
751
|
+
|
|
752
|
+
const di = await collectDeviceIntelligence({
|
|
753
|
+
platformVersion: 'shared@3.6.2', // optional — defaults to SHARED_SDK_PLATFORM
|
|
754
|
+
overrides: { vpn_detected: true }, // optional — merged on top of collected data
|
|
755
|
+
});
|
|
756
|
+
|
|
757
|
+
if (di) {
|
|
758
|
+
console.log(di.ip); // '1.2.3.4'
|
|
759
|
+
console.log(di.country); // 'US'
|
|
760
|
+
console.log(di.isp); // 'Comcast Cable'
|
|
761
|
+
console.log(di.platform_version); // 'shared@3.6.2'
|
|
762
|
+
}
|
|
763
|
+
// Returns null if ipinfo.io is unreachable — handle gracefully
|
|
764
|
+
```
|
|
765
|
+
|
|
766
|
+
> If you import from `@moveris/react`, use that package's `collectDeviceIntelligence` instead — it pre-bakes `REACT_SDK_PLATFORM` as the default `platformVersion` so the full `react@A.B.C+shared@X.Y.Z` string is used automatically.
|
|
767
|
+
|
|
768
|
+
### `SHARED_SDK_PLATFORM`
|
|
769
|
+
|
|
770
|
+
Pre-formatted platform string for the `platform_version` field. Reads the version from `package.json` at build time — never goes stale.
|
|
771
|
+
|
|
772
|
+
```typescript
|
|
773
|
+
import { SHARED_SDK_PLATFORM } from '@moveris/shared';
|
|
774
|
+
|
|
775
|
+
console.log(SHARED_SDK_PLATFORM); // 'shared@3.6.2'
|
|
776
|
+
```
|
|
777
|
+
|
|
778
|
+
### Device Intelligence Types
|
|
779
|
+
|
|
780
|
+
```typescript
|
|
781
|
+
import type {
|
|
782
|
+
DeviceIntelligence,
|
|
783
|
+
DeviceIntelligenceOverrides,
|
|
784
|
+
DeviceIntelligenceGeo,
|
|
785
|
+
DeviceIntelligenceCamera,
|
|
786
|
+
} from '@moveris/shared';
|
|
787
|
+
```
|
|
788
|
+
|
|
789
|
+
```typescript
|
|
790
|
+
interface DeviceIntelligence {
|
|
791
|
+
ip: string;
|
|
792
|
+
country: string; // ISO 3166-1 alpha-2, e.g. 'US'
|
|
793
|
+
region: string; // e.g. 'California'
|
|
794
|
+
city: string; // e.g. 'San Francisco'
|
|
795
|
+
isp?: string; // Internet service provider
|
|
796
|
+
user_agent?: string; // navigator.userAgent
|
|
797
|
+
platform_version?: string; // SDK version string
|
|
798
|
+
vpn_detected?: boolean;
|
|
799
|
+
camera?: DeviceIntelligenceCamera;
|
|
800
|
+
}
|
|
801
|
+
|
|
802
|
+
interface DeviceIntelligenceCamera {
|
|
803
|
+
device_name?: string; // e.g. 'FaceTime HD Camera'
|
|
804
|
+
resolution?: string; // e.g. '1280x720'
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
interface DeviceIntelligenceOverrides {
|
|
808
|
+
vpn_detected?: boolean;
|
|
809
|
+
camera?: DeviceIntelligenceCamera;
|
|
810
|
+
[key: string]: unknown;
|
|
811
|
+
}
|
|
812
|
+
```
|
|
813
|
+
|
|
814
|
+
### CSP Note
|
|
815
|
+
|
|
816
|
+
If your app enforces a Content Security Policy, add `https://ipinfo.io` to `connect-src`:
|
|
817
|
+
|
|
818
|
+
```
|
|
819
|
+
connect-src 'self' https://api.moveris.com https://ipinfo.io;
|
|
820
|
+
```
|
|
821
|
+
|
|
822
|
+
Without this, the ipinfo.io fetch will be blocked silently and `device_intelligence` will be omitted from all requests.
|
|
823
|
+
|
|
824
|
+
---
|
|
825
|
+
|
|
729
826
|
## Configuration Constants
|
|
730
827
|
|
|
731
828
|
```typescript
|
|
@@ -767,6 +864,11 @@ import type {
|
|
|
767
864
|
EyeQualityThresholds,
|
|
768
865
|
EyeRegionBounds,
|
|
769
866
|
EyeRegionsBounds,
|
|
867
|
+
// Device Intelligence Types
|
|
868
|
+
DeviceIntelligence,
|
|
869
|
+
DeviceIntelligenceOverrides,
|
|
870
|
+
DeviceIntelligenceGeo,
|
|
871
|
+
DeviceIntelligenceCamera,
|
|
770
872
|
} from '@moveris/shared';
|
|
771
873
|
```
|
|
772
874
|
|
package/dist/index.d.mts
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
interface DeviceIntelligenceGeo {
|
|
2
|
+
country: string;
|
|
3
|
+
region: string;
|
|
4
|
+
city: string;
|
|
5
|
+
isp?: string;
|
|
6
|
+
}
|
|
7
|
+
interface DeviceIntelligenceCamera {
|
|
8
|
+
device_name: string;
|
|
9
|
+
resolution: string;
|
|
10
|
+
}
|
|
11
|
+
interface DeviceIntelligence {
|
|
12
|
+
ip_address: string;
|
|
13
|
+
geo: DeviceIntelligenceGeo;
|
|
14
|
+
vpn_detected: boolean;
|
|
15
|
+
camera: DeviceIntelligenceCamera;
|
|
16
|
+
user_agent: string;
|
|
17
|
+
platform_version: string;
|
|
18
|
+
}
|
|
19
|
+
type DeviceIntelligenceOverrides = {
|
|
20
|
+
ip_address?: string;
|
|
21
|
+
geo?: Partial<DeviceIntelligenceGeo>;
|
|
22
|
+
vpn_detected?: boolean;
|
|
23
|
+
camera?: Partial<DeviceIntelligenceCamera>;
|
|
24
|
+
user_agent?: string;
|
|
25
|
+
platform_version?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
1
28
|
type Verdict = 'live' | 'fake' | 'inconclusive';
|
|
2
29
|
interface ModelEntry {
|
|
3
30
|
id: string;
|
|
@@ -40,6 +67,7 @@ interface FastCheckRequest {
|
|
|
40
67
|
frames: FrameData[];
|
|
41
68
|
frame_count?: number;
|
|
42
69
|
warnings?: string[];
|
|
70
|
+
device_intelligence?: DeviceIntelligence;
|
|
43
71
|
}
|
|
44
72
|
interface FastCheckCropsRequest {
|
|
45
73
|
session_id: string;
|
|
@@ -47,6 +75,7 @@ interface FastCheckCropsRequest {
|
|
|
47
75
|
source?: FrameSource;
|
|
48
76
|
crops: CropData[];
|
|
49
77
|
frame_count?: number;
|
|
78
|
+
device_intelligence?: DeviceIntelligence;
|
|
50
79
|
}
|
|
51
80
|
interface VerifyRequest {
|
|
52
81
|
session_id: string;
|
|
@@ -78,6 +107,7 @@ interface FastCheckStreamRequest {
|
|
|
78
107
|
frame: FrameData;
|
|
79
108
|
frame_count?: number;
|
|
80
109
|
warnings?: string[];
|
|
110
|
+
device_intelligence?: DeviceIntelligence;
|
|
81
111
|
}
|
|
82
112
|
interface FastCheckResponse {
|
|
83
113
|
verdict: Verdict | null;
|
|
@@ -539,6 +569,7 @@ interface LivenessClientConfig {
|
|
|
539
569
|
timeout?: number;
|
|
540
570
|
enableRetry?: boolean;
|
|
541
571
|
customFetch?: typeof fetch;
|
|
572
|
+
deviceIntelligenceOverrides?: DeviceIntelligenceOverrides;
|
|
542
573
|
}
|
|
543
574
|
declare class LivenessApiError extends Error {
|
|
544
575
|
readonly code: string;
|
|
@@ -559,7 +590,13 @@ declare class LivenessClient {
|
|
|
559
590
|
private readonly timeout;
|
|
560
591
|
private readonly enableRetry;
|
|
561
592
|
private readonly fetchFn;
|
|
593
|
+
private diCollected;
|
|
594
|
+
private diCollecting;
|
|
595
|
+
private diOverrides;
|
|
562
596
|
constructor(config: LivenessClientConfig);
|
|
597
|
+
updateDeviceIntelligenceOverrides(partial: DeviceIntelligenceOverrides): void;
|
|
598
|
+
private getDeviceIntelligence;
|
|
599
|
+
private applyDiOverrides;
|
|
563
600
|
private request;
|
|
564
601
|
private requestRaw;
|
|
565
602
|
private parseErrorResponse;
|
|
@@ -902,4 +939,10 @@ declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray
|
|
|
902
939
|
declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
|
|
903
940
|
declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
|
|
904
941
|
|
|
905
|
-
|
|
942
|
+
declare const SHARED_SDK_PLATFORM: string;
|
|
943
|
+
declare function collectDeviceIntelligence(opts?: {
|
|
944
|
+
overrides?: DeviceIntelligenceOverrides;
|
|
945
|
+
platformVersion?: string;
|
|
946
|
+
}): Promise<DeviceIntelligence | null>;
|
|
947
|
+
|
|
948
|
+
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 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 EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_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, calculateAdaptiveCropMultiplier, 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 };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,30 @@
|
|
|
1
|
+
interface DeviceIntelligenceGeo {
|
|
2
|
+
country: string;
|
|
3
|
+
region: string;
|
|
4
|
+
city: string;
|
|
5
|
+
isp?: string;
|
|
6
|
+
}
|
|
7
|
+
interface DeviceIntelligenceCamera {
|
|
8
|
+
device_name: string;
|
|
9
|
+
resolution: string;
|
|
10
|
+
}
|
|
11
|
+
interface DeviceIntelligence {
|
|
12
|
+
ip_address: string;
|
|
13
|
+
geo: DeviceIntelligenceGeo;
|
|
14
|
+
vpn_detected: boolean;
|
|
15
|
+
camera: DeviceIntelligenceCamera;
|
|
16
|
+
user_agent: string;
|
|
17
|
+
platform_version: string;
|
|
18
|
+
}
|
|
19
|
+
type DeviceIntelligenceOverrides = {
|
|
20
|
+
ip_address?: string;
|
|
21
|
+
geo?: Partial<DeviceIntelligenceGeo>;
|
|
22
|
+
vpn_detected?: boolean;
|
|
23
|
+
camera?: Partial<DeviceIntelligenceCamera>;
|
|
24
|
+
user_agent?: string;
|
|
25
|
+
platform_version?: string;
|
|
26
|
+
};
|
|
27
|
+
|
|
1
28
|
type Verdict = 'live' | 'fake' | 'inconclusive';
|
|
2
29
|
interface ModelEntry {
|
|
3
30
|
id: string;
|
|
@@ -40,6 +67,7 @@ interface FastCheckRequest {
|
|
|
40
67
|
frames: FrameData[];
|
|
41
68
|
frame_count?: number;
|
|
42
69
|
warnings?: string[];
|
|
70
|
+
device_intelligence?: DeviceIntelligence;
|
|
43
71
|
}
|
|
44
72
|
interface FastCheckCropsRequest {
|
|
45
73
|
session_id: string;
|
|
@@ -47,6 +75,7 @@ interface FastCheckCropsRequest {
|
|
|
47
75
|
source?: FrameSource;
|
|
48
76
|
crops: CropData[];
|
|
49
77
|
frame_count?: number;
|
|
78
|
+
device_intelligence?: DeviceIntelligence;
|
|
50
79
|
}
|
|
51
80
|
interface VerifyRequest {
|
|
52
81
|
session_id: string;
|
|
@@ -78,6 +107,7 @@ interface FastCheckStreamRequest {
|
|
|
78
107
|
frame: FrameData;
|
|
79
108
|
frame_count?: number;
|
|
80
109
|
warnings?: string[];
|
|
110
|
+
device_intelligence?: DeviceIntelligence;
|
|
81
111
|
}
|
|
82
112
|
interface FastCheckResponse {
|
|
83
113
|
verdict: Verdict | null;
|
|
@@ -539,6 +569,7 @@ interface LivenessClientConfig {
|
|
|
539
569
|
timeout?: number;
|
|
540
570
|
enableRetry?: boolean;
|
|
541
571
|
customFetch?: typeof fetch;
|
|
572
|
+
deviceIntelligenceOverrides?: DeviceIntelligenceOverrides;
|
|
542
573
|
}
|
|
543
574
|
declare class LivenessApiError extends Error {
|
|
544
575
|
readonly code: string;
|
|
@@ -559,7 +590,13 @@ declare class LivenessClient {
|
|
|
559
590
|
private readonly timeout;
|
|
560
591
|
private readonly enableRetry;
|
|
561
592
|
private readonly fetchFn;
|
|
593
|
+
private diCollected;
|
|
594
|
+
private diCollecting;
|
|
595
|
+
private diOverrides;
|
|
562
596
|
constructor(config: LivenessClientConfig);
|
|
597
|
+
updateDeviceIntelligenceOverrides(partial: DeviceIntelligenceOverrides): void;
|
|
598
|
+
private getDeviceIntelligence;
|
|
599
|
+
private applyDiOverrides;
|
|
563
600
|
private request;
|
|
564
601
|
private requestRaw;
|
|
565
602
|
private parseErrorResponse;
|
|
@@ -902,4 +939,10 @@ declare function analyzeEyeRegionContrast(pixels: Uint8Array | Uint8ClampedArray
|
|
|
902
939
|
declare function detectSpecularHighlights(pixels: Uint8Array | Uint8ClampedArray, relativeFactor?: number, meanBrightness?: number): number;
|
|
903
940
|
declare function checkEyeRegionQuality(pixels: Uint8Array | Uint8ClampedArray, thresholds?: EyeQualityThresholds): EyeRegionQuality;
|
|
904
941
|
|
|
905
|
-
|
|
942
|
+
declare const SHARED_SDK_PLATFORM: string;
|
|
943
|
+
declare function collectDeviceIntelligence(opts?: {
|
|
944
|
+
overrides?: DeviceIntelligenceOverrides;
|
|
945
|
+
platformVersion?: string;
|
|
946
|
+
}): Promise<DeviceIntelligence | null>;
|
|
947
|
+
|
|
948
|
+
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 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 EyeQualityThresholds, type EyeRegionBounds, type EyeRegionQuality, type EyeRegionsBounds, FACE_CENTER_VERTICAL_OFFSET, FACE_CROP_OUTPUT_SIZE, FEEDBACK_MESSAGES, FRAME_BUFFER_CONFIG, FRAME_CONFIG, type FaceAlignmentResult, type FaceBoundingBox, type FaceDetectionTiers, type FaceInOvalResult, type FaceLandmarkPoint, type FaceRollResult, type FaceVisibilityResult, type FastCheckCropsRequest, type FastCheckModel, type FastCheckRequest, type FastCheckResponse, type FastCheckStreamRequest, type FastCheckStreamResponse, type FeedbackLocale, type FeedbackMessageKey, type Frame, FrameBuffer, type FrameData, type FrameQualityResult, FrameQueue, type FrameSource, GOOD_ALIGNMENT, type GazeThresholds, HIGH_ALIGNMENT, HYBRID_MODEL_CONFIGS, type HandOcclusionConfig, type HeadPose, type HealthResponse, type Hybrid150CheckRequest, type Hybrid50CheckRequest, type HybridCheckRequest, type HybridCheckResponse, type HybridFrameData, type HybridModelConfig, IDEAL_CROP_MULTIPLIER, type JobStatus, type JobStatusResponse, LANDMARK_INDEX, LANDMARK_MAX_BOUND, LANDMARK_MIN_BOUND, LOW_LIGHT_THRESHOLD, type LandmarkValidationResult, type LightingAnalysis, LivenessApiError, type LivenessCallbacks, LivenessClient, type LivenessClientConfig, type LivenessConfig, type LivenessResult, type LivenessState, MAX_CROP_MULTIPLIER, MAX_FACE_PERCENTAGE_IN_CROP, MAX_FACE_RATIO, MAX_FACE_ROLL_DEGREES, MAX_IDEAL_FACE_RATIO, MIN_CAPTURE_ALIGNMENT, MIN_CROP_MULTIPLIER, MIN_FACE_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, calculateAdaptiveCropMultiplier, 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 };
|
package/dist/index.js
CHANGED
|
@@ -87,6 +87,7 @@ __export(index_exports, {
|
|
|
87
87
|
OVAL_REGION_DESKTOP: () => OVAL_REGION_DESKTOP,
|
|
88
88
|
OVAL_REGION_MOBILE: () => OVAL_REGION_MOBILE,
|
|
89
89
|
RETRY_CONFIG: () => RETRY_CONFIG,
|
|
90
|
+
SHARED_SDK_PLATFORM: () => SHARED_SDK_PLATFORM,
|
|
90
91
|
TARGET_FACE_PERCENTAGE_IN_CROP: () => TARGET_FACE_PERCENTAGE_IN_CROP,
|
|
91
92
|
VALID_FRAME_COUNTS: () => VALID_FRAME_COUNTS,
|
|
92
93
|
analyzeBlur: () => analyzeBlur,
|
|
@@ -101,6 +102,7 @@ __export(index_exports, {
|
|
|
101
102
|
canCaptureFrame: () => canCaptureFrame,
|
|
102
103
|
checkEyeRegionQuality: () => checkEyeRegionQuality,
|
|
103
104
|
checkFrameQuality: () => checkFrameQuality,
|
|
105
|
+
collectDeviceIntelligence: () => collectDeviceIntelligence,
|
|
104
106
|
decodeBase64: () => decodeBase64,
|
|
105
107
|
detectCameraAngle: () => detectCameraAngle,
|
|
106
108
|
detectFaceRoll: () => detectFaceRoll,
|
|
@@ -239,6 +241,55 @@ async function sleep(ms) {
|
|
|
239
241
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
240
242
|
}
|
|
241
243
|
|
|
244
|
+
// package.json
|
|
245
|
+
var version = "3.8.1";
|
|
246
|
+
|
|
247
|
+
// src/utils/deviceIntelligence.ts
|
|
248
|
+
var IPINFO_URL = "https://ipinfo.io/json";
|
|
249
|
+
var SHARED_SDK_VERSION = version;
|
|
250
|
+
var SHARED_SDK_PLATFORM = `shared@${SHARED_SDK_VERSION}`;
|
|
251
|
+
function parseIsp(org) {
|
|
252
|
+
if (!org) return void 0;
|
|
253
|
+
return org.replace(/^AS\d+\s+/, "").trim() || void 0;
|
|
254
|
+
}
|
|
255
|
+
function mergeOverrides(collected, overrides) {
|
|
256
|
+
if (!overrides) return collected;
|
|
257
|
+
return {
|
|
258
|
+
...collected,
|
|
259
|
+
...overrides,
|
|
260
|
+
geo: { ...collected.geo, ...overrides.geo },
|
|
261
|
+
camera: { ...collected.camera, ...overrides.camera }
|
|
262
|
+
};
|
|
263
|
+
}
|
|
264
|
+
async function collectDeviceIntelligence(opts) {
|
|
265
|
+
try {
|
|
266
|
+
const response = await fetch(IPINFO_URL);
|
|
267
|
+
if (!response.ok) return null;
|
|
268
|
+
const data = await response.json();
|
|
269
|
+
if (!data.ip) return null;
|
|
270
|
+
const isp = parseIsp(data.org);
|
|
271
|
+
const collected = {
|
|
272
|
+
ip_address: data.ip,
|
|
273
|
+
geo: {
|
|
274
|
+
country: data.country ?? "Unknown",
|
|
275
|
+
region: data.region ?? "Unknown",
|
|
276
|
+
city: data.city ?? "Unknown",
|
|
277
|
+
...isp ? { isp } : {}
|
|
278
|
+
},
|
|
279
|
+
vpn_detected: false,
|
|
280
|
+
camera: {
|
|
281
|
+
device_name: "Unknown",
|
|
282
|
+
resolution: "Unknown"
|
|
283
|
+
},
|
|
284
|
+
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "Unknown",
|
|
285
|
+
platform_version: opts?.platformVersion ?? SHARED_SDK_PLATFORM
|
|
286
|
+
};
|
|
287
|
+
return mergeOverrides(collected, opts?.overrides);
|
|
288
|
+
} catch {
|
|
289
|
+
return null;
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
242
293
|
// src/client/LivenessClient.ts
|
|
243
294
|
var LivenessApiError = class extends Error {
|
|
244
295
|
constructor(message, code, statusCode, required, received) {
|
|
@@ -328,12 +379,58 @@ function generateSessionId() {
|
|
|
328
379
|
}
|
|
329
380
|
var LivenessClient = class _LivenessClient {
|
|
330
381
|
constructor(config) {
|
|
382
|
+
// Device intelligence: lazily collected on first API call, then cached.
|
|
383
|
+
// undefined = not yet attempted, null = collection failed.
|
|
384
|
+
this.diCollected = void 0;
|
|
385
|
+
this.diCollecting = null;
|
|
331
386
|
this.baseUrl = (config.baseUrl ?? DEFAULT_ENDPOINT).replace(/\/$/, "");
|
|
332
387
|
this.apiKey = config.apiKey;
|
|
333
388
|
this.modelVersion = config.modelVersion;
|
|
334
389
|
this.timeout = config.timeout ?? AUTH_CONFIG.timeout;
|
|
335
390
|
this.enableRetry = config.enableRetry ?? true;
|
|
336
391
|
this.fetchFn = config.customFetch ?? (typeof window !== "undefined" ? fetch.bind(window) : fetch);
|
|
392
|
+
this.diOverrides = { ...config.deviceIntelligenceOverrides };
|
|
393
|
+
}
|
|
394
|
+
/**
|
|
395
|
+
* Merge additional device intelligence overrides into the existing set.
|
|
396
|
+
* Called by the React layer to inject camera info once the stream is active.
|
|
397
|
+
* Overrides deep-merge — only specified keys are replaced.
|
|
398
|
+
*/
|
|
399
|
+
updateDeviceIntelligenceOverrides(partial) {
|
|
400
|
+
this.diOverrides = {
|
|
401
|
+
...this.diOverrides,
|
|
402
|
+
...partial,
|
|
403
|
+
...partial.geo ? { geo: { ...this.diOverrides.geo, ...partial.geo } } : {},
|
|
404
|
+
...partial.camera ? { camera: { ...this.diOverrides.camera, ...partial.camera } } : {}
|
|
405
|
+
};
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Return the merged device intelligence (auto-collected + overrides).
|
|
409
|
+
* Collection is lazy — runs once on first call, then returns cached result.
|
|
410
|
+
* Returns null if collection failed; callers should omit the field in that case.
|
|
411
|
+
*/
|
|
412
|
+
async getDeviceIntelligence() {
|
|
413
|
+
if (this.diCollected !== void 0) {
|
|
414
|
+
return this.diCollected ? this.applyDiOverrides(this.diCollected) : null;
|
|
415
|
+
}
|
|
416
|
+
if (!this.diCollecting) {
|
|
417
|
+
this.diCollecting = collectDeviceIntelligence({
|
|
418
|
+
platformVersion: SHARED_SDK_PLATFORM
|
|
419
|
+
}).then((result) => {
|
|
420
|
+
this.diCollected = result ?? null;
|
|
421
|
+
});
|
|
422
|
+
}
|
|
423
|
+
await this.diCollecting;
|
|
424
|
+
return this.diCollected ? this.applyDiOverrides(this.diCollected) : null;
|
|
425
|
+
}
|
|
426
|
+
applyDiOverrides(collected) {
|
|
427
|
+
const ov = this.diOverrides;
|
|
428
|
+
return {
|
|
429
|
+
...collected,
|
|
430
|
+
...ov,
|
|
431
|
+
geo: { ...collected.geo, ...ov.geo },
|
|
432
|
+
camera: { ...collected.camera, ...ov.camera }
|
|
433
|
+
};
|
|
337
434
|
}
|
|
338
435
|
/**
|
|
339
436
|
* Make an authenticated API request, returning the parsed body.
|
|
@@ -486,9 +583,9 @@ var LivenessClient = class _LivenessClient {
|
|
|
486
583
|
* Build extra request headers for model versioning.
|
|
487
584
|
*/
|
|
488
585
|
buildModelVersionHeaders(modelVersion) {
|
|
489
|
-
const
|
|
490
|
-
if (!
|
|
491
|
-
return { [AUTH_CONFIG.modelVersionHeader]:
|
|
586
|
+
const version2 = modelVersion ?? this.modelVersion;
|
|
587
|
+
if (!version2) return {};
|
|
588
|
+
return { [AUTH_CONFIG.modelVersionHeader]: version2 };
|
|
492
589
|
}
|
|
493
590
|
/**
|
|
494
591
|
* Make a request with optional retry
|
|
@@ -553,13 +650,15 @@ var LivenessClient = class _LivenessClient {
|
|
|
553
650
|
*/
|
|
554
651
|
async fastCheck(frames, options = {}) {
|
|
555
652
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
653
|
+
const di = await this.getDeviceIntelligence();
|
|
556
654
|
const request = {
|
|
557
655
|
session_id: options.sessionId ?? generateSessionId(),
|
|
558
656
|
model: options.model ?? "10",
|
|
559
657
|
source: options.source ?? "live",
|
|
560
658
|
frames: toFrameData(frames),
|
|
561
659
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
562
|
-
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
660
|
+
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
661
|
+
...di ? { device_intelligence: di } : {}
|
|
563
662
|
};
|
|
564
663
|
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
565
664
|
API_PATHS.fastCheck,
|
|
@@ -587,6 +686,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
587
686
|
*/
|
|
588
687
|
async fastCheckCrops(crops, options = {}) {
|
|
589
688
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
689
|
+
const di = await this.getDeviceIntelligence();
|
|
590
690
|
const request = {
|
|
591
691
|
session_id: options.sessionId ?? generateSessionId(),
|
|
592
692
|
model: options.model ?? "10",
|
|
@@ -594,7 +694,8 @@ var LivenessClient = class _LivenessClient {
|
|
|
594
694
|
crops,
|
|
595
695
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
596
696
|
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
597
|
-
...options.bgSegmentation !== void 0 ? { bg_segmentation: options.bgSegmentation } : {}
|
|
697
|
+
...options.bgSegmentation !== void 0 ? { bg_segmentation: options.bgSegmentation } : {},
|
|
698
|
+
...di ? { device_intelligence: di } : {}
|
|
598
699
|
};
|
|
599
700
|
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
600
701
|
API_PATHS.fastCheckCrops,
|
|
@@ -650,13 +751,15 @@ var LivenessClient = class _LivenessClient {
|
|
|
650
751
|
*/
|
|
651
752
|
async sendStreamFrameInternal(frameData, options) {
|
|
652
753
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
754
|
+
const di = await this.getDeviceIntelligence();
|
|
653
755
|
const request = {
|
|
654
756
|
session_id: options.sessionId,
|
|
655
757
|
model: options.model,
|
|
656
758
|
source: options.source,
|
|
657
759
|
frame: frameData,
|
|
658
760
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
659
|
-
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
761
|
+
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
762
|
+
...di ? { device_intelligence: di } : {}
|
|
660
763
|
};
|
|
661
764
|
return this.requestWithRetry(API_PATHS.fastCheckStream, {
|
|
662
765
|
method: "POST",
|
|
@@ -2314,6 +2417,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2314
2417
|
OVAL_REGION_DESKTOP,
|
|
2315
2418
|
OVAL_REGION_MOBILE,
|
|
2316
2419
|
RETRY_CONFIG,
|
|
2420
|
+
SHARED_SDK_PLATFORM,
|
|
2317
2421
|
TARGET_FACE_PERCENTAGE_IN_CROP,
|
|
2318
2422
|
VALID_FRAME_COUNTS,
|
|
2319
2423
|
analyzeBlur,
|
|
@@ -2328,6 +2432,7 @@ function checkEyeRegionQuality(pixels, thresholds = EYE_QUALITY_THRESHOLDS) {
|
|
|
2328
2432
|
canCaptureFrame,
|
|
2329
2433
|
checkEyeRegionQuality,
|
|
2330
2434
|
checkFrameQuality,
|
|
2435
|
+
collectDeviceIntelligence,
|
|
2331
2436
|
decodeBase64,
|
|
2332
2437
|
detectCameraAngle,
|
|
2333
2438
|
detectFaceRoll,
|
package/dist/index.mjs
CHANGED
|
@@ -95,6 +95,55 @@ async function sleep(ms) {
|
|
|
95
95
|
await new Promise((resolve) => setTimeout(resolve, ms));
|
|
96
96
|
}
|
|
97
97
|
|
|
98
|
+
// package.json
|
|
99
|
+
var version = "3.8.1";
|
|
100
|
+
|
|
101
|
+
// src/utils/deviceIntelligence.ts
|
|
102
|
+
var IPINFO_URL = "https://ipinfo.io/json";
|
|
103
|
+
var SHARED_SDK_VERSION = version;
|
|
104
|
+
var SHARED_SDK_PLATFORM = `shared@${SHARED_SDK_VERSION}`;
|
|
105
|
+
function parseIsp(org) {
|
|
106
|
+
if (!org) return void 0;
|
|
107
|
+
return org.replace(/^AS\d+\s+/, "").trim() || void 0;
|
|
108
|
+
}
|
|
109
|
+
function mergeOverrides(collected, overrides) {
|
|
110
|
+
if (!overrides) return collected;
|
|
111
|
+
return {
|
|
112
|
+
...collected,
|
|
113
|
+
...overrides,
|
|
114
|
+
geo: { ...collected.geo, ...overrides.geo },
|
|
115
|
+
camera: { ...collected.camera, ...overrides.camera }
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
async function collectDeviceIntelligence(opts) {
|
|
119
|
+
try {
|
|
120
|
+
const response = await fetch(IPINFO_URL);
|
|
121
|
+
if (!response.ok) return null;
|
|
122
|
+
const data = await response.json();
|
|
123
|
+
if (!data.ip) return null;
|
|
124
|
+
const isp = parseIsp(data.org);
|
|
125
|
+
const collected = {
|
|
126
|
+
ip_address: data.ip,
|
|
127
|
+
geo: {
|
|
128
|
+
country: data.country ?? "Unknown",
|
|
129
|
+
region: data.region ?? "Unknown",
|
|
130
|
+
city: data.city ?? "Unknown",
|
|
131
|
+
...isp ? { isp } : {}
|
|
132
|
+
},
|
|
133
|
+
vpn_detected: false,
|
|
134
|
+
camera: {
|
|
135
|
+
device_name: "Unknown",
|
|
136
|
+
resolution: "Unknown"
|
|
137
|
+
},
|
|
138
|
+
user_agent: typeof navigator !== "undefined" ? navigator.userAgent : "Unknown",
|
|
139
|
+
platform_version: opts?.platformVersion ?? SHARED_SDK_PLATFORM
|
|
140
|
+
};
|
|
141
|
+
return mergeOverrides(collected, opts?.overrides);
|
|
142
|
+
} catch {
|
|
143
|
+
return null;
|
|
144
|
+
}
|
|
145
|
+
}
|
|
146
|
+
|
|
98
147
|
// src/client/LivenessClient.ts
|
|
99
148
|
var LivenessApiError = class extends Error {
|
|
100
149
|
constructor(message, code, statusCode, required, received) {
|
|
@@ -184,12 +233,58 @@ function generateSessionId() {
|
|
|
184
233
|
}
|
|
185
234
|
var LivenessClient = class _LivenessClient {
|
|
186
235
|
constructor(config) {
|
|
236
|
+
// Device intelligence: lazily collected on first API call, then cached.
|
|
237
|
+
// undefined = not yet attempted, null = collection failed.
|
|
238
|
+
this.diCollected = void 0;
|
|
239
|
+
this.diCollecting = null;
|
|
187
240
|
this.baseUrl = (config.baseUrl ?? DEFAULT_ENDPOINT).replace(/\/$/, "");
|
|
188
241
|
this.apiKey = config.apiKey;
|
|
189
242
|
this.modelVersion = config.modelVersion;
|
|
190
243
|
this.timeout = config.timeout ?? AUTH_CONFIG.timeout;
|
|
191
244
|
this.enableRetry = config.enableRetry ?? true;
|
|
192
245
|
this.fetchFn = config.customFetch ?? (typeof window !== "undefined" ? fetch.bind(window) : fetch);
|
|
246
|
+
this.diOverrides = { ...config.deviceIntelligenceOverrides };
|
|
247
|
+
}
|
|
248
|
+
/**
|
|
249
|
+
* Merge additional device intelligence overrides into the existing set.
|
|
250
|
+
* Called by the React layer to inject camera info once the stream is active.
|
|
251
|
+
* Overrides deep-merge — only specified keys are replaced.
|
|
252
|
+
*/
|
|
253
|
+
updateDeviceIntelligenceOverrides(partial) {
|
|
254
|
+
this.diOverrides = {
|
|
255
|
+
...this.diOverrides,
|
|
256
|
+
...partial,
|
|
257
|
+
...partial.geo ? { geo: { ...this.diOverrides.geo, ...partial.geo } } : {},
|
|
258
|
+
...partial.camera ? { camera: { ...this.diOverrides.camera, ...partial.camera } } : {}
|
|
259
|
+
};
|
|
260
|
+
}
|
|
261
|
+
/**
|
|
262
|
+
* Return the merged device intelligence (auto-collected + overrides).
|
|
263
|
+
* Collection is lazy — runs once on first call, then returns cached result.
|
|
264
|
+
* Returns null if collection failed; callers should omit the field in that case.
|
|
265
|
+
*/
|
|
266
|
+
async getDeviceIntelligence() {
|
|
267
|
+
if (this.diCollected !== void 0) {
|
|
268
|
+
return this.diCollected ? this.applyDiOverrides(this.diCollected) : null;
|
|
269
|
+
}
|
|
270
|
+
if (!this.diCollecting) {
|
|
271
|
+
this.diCollecting = collectDeviceIntelligence({
|
|
272
|
+
platformVersion: SHARED_SDK_PLATFORM
|
|
273
|
+
}).then((result) => {
|
|
274
|
+
this.diCollected = result ?? null;
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
await this.diCollecting;
|
|
278
|
+
return this.diCollected ? this.applyDiOverrides(this.diCollected) : null;
|
|
279
|
+
}
|
|
280
|
+
applyDiOverrides(collected) {
|
|
281
|
+
const ov = this.diOverrides;
|
|
282
|
+
return {
|
|
283
|
+
...collected,
|
|
284
|
+
...ov,
|
|
285
|
+
geo: { ...collected.geo, ...ov.geo },
|
|
286
|
+
camera: { ...collected.camera, ...ov.camera }
|
|
287
|
+
};
|
|
193
288
|
}
|
|
194
289
|
/**
|
|
195
290
|
* Make an authenticated API request, returning the parsed body.
|
|
@@ -342,9 +437,9 @@ var LivenessClient = class _LivenessClient {
|
|
|
342
437
|
* Build extra request headers for model versioning.
|
|
343
438
|
*/
|
|
344
439
|
buildModelVersionHeaders(modelVersion) {
|
|
345
|
-
const
|
|
346
|
-
if (!
|
|
347
|
-
return { [AUTH_CONFIG.modelVersionHeader]:
|
|
440
|
+
const version2 = modelVersion ?? this.modelVersion;
|
|
441
|
+
if (!version2) return {};
|
|
442
|
+
return { [AUTH_CONFIG.modelVersionHeader]: version2 };
|
|
348
443
|
}
|
|
349
444
|
/**
|
|
350
445
|
* Make a request with optional retry
|
|
@@ -409,13 +504,15 @@ var LivenessClient = class _LivenessClient {
|
|
|
409
504
|
*/
|
|
410
505
|
async fastCheck(frames, options = {}) {
|
|
411
506
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
507
|
+
const di = await this.getDeviceIntelligence();
|
|
412
508
|
const request = {
|
|
413
509
|
session_id: options.sessionId ?? generateSessionId(),
|
|
414
510
|
model: options.model ?? "10",
|
|
415
511
|
source: options.source ?? "live",
|
|
416
512
|
frames: toFrameData(frames),
|
|
417
513
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
418
|
-
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
514
|
+
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
515
|
+
...di ? { device_intelligence: di } : {}
|
|
419
516
|
};
|
|
420
517
|
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
421
518
|
API_PATHS.fastCheck,
|
|
@@ -443,6 +540,7 @@ var LivenessClient = class _LivenessClient {
|
|
|
443
540
|
*/
|
|
444
541
|
async fastCheckCrops(crops, options = {}) {
|
|
445
542
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
543
|
+
const di = await this.getDeviceIntelligence();
|
|
446
544
|
const request = {
|
|
447
545
|
session_id: options.sessionId ?? generateSessionId(),
|
|
448
546
|
model: options.model ?? "10",
|
|
@@ -450,7 +548,8 @@ var LivenessClient = class _LivenessClient {
|
|
|
450
548
|
crops,
|
|
451
549
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
452
550
|
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
453
|
-
...options.bgSegmentation !== void 0 ? { bg_segmentation: options.bgSegmentation } : {}
|
|
551
|
+
...options.bgSegmentation !== void 0 ? { bg_segmentation: options.bgSegmentation } : {},
|
|
552
|
+
...di ? { device_intelligence: di } : {}
|
|
454
553
|
};
|
|
455
554
|
const { data: response, headers } = await this.requestWithRetryRaw(
|
|
456
555
|
API_PATHS.fastCheckCrops,
|
|
@@ -506,13 +605,15 @@ var LivenessClient = class _LivenessClient {
|
|
|
506
605
|
*/
|
|
507
606
|
async sendStreamFrameInternal(frameData, options) {
|
|
508
607
|
const effectiveVersion = options.modelVersion ?? this.modelVersion;
|
|
608
|
+
const di = await this.getDeviceIntelligence();
|
|
509
609
|
const request = {
|
|
510
610
|
session_id: options.sessionId,
|
|
511
611
|
model: options.model,
|
|
512
612
|
source: options.source,
|
|
513
613
|
frame: frameData,
|
|
514
614
|
...options.frameCount != null ? { frame_count: options.frameCount } : {},
|
|
515
|
-
...options.warnings?.length ? { warnings: options.warnings } : {}
|
|
615
|
+
...options.warnings?.length ? { warnings: options.warnings } : {},
|
|
616
|
+
...di ? { device_intelligence: di } : {}
|
|
516
617
|
};
|
|
517
618
|
return this.requestWithRetry(API_PATHS.fastCheckStream, {
|
|
518
619
|
method: "POST",
|
|
@@ -2169,6 +2270,7 @@ export {
|
|
|
2169
2270
|
OVAL_REGION_DESKTOP,
|
|
2170
2271
|
OVAL_REGION_MOBILE,
|
|
2171
2272
|
RETRY_CONFIG,
|
|
2273
|
+
SHARED_SDK_PLATFORM,
|
|
2172
2274
|
TARGET_FACE_PERCENTAGE_IN_CROP,
|
|
2173
2275
|
VALID_FRAME_COUNTS,
|
|
2174
2276
|
analyzeBlur,
|
|
@@ -2183,6 +2285,7 @@ export {
|
|
|
2183
2285
|
canCaptureFrame,
|
|
2184
2286
|
checkEyeRegionQuality,
|
|
2185
2287
|
checkFrameQuality,
|
|
2288
|
+
collectDeviceIntelligence,
|
|
2186
2289
|
decodeBase64,
|
|
2187
2290
|
detectCameraAngle,
|
|
2188
2291
|
detectFaceRoll,
|