@smileid/usesmileid 12.2.0 → 12.3.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/CHANGELOG.md +5 -1
- package/README.md +57 -18
- package/dist/camera/bounding_box_metering_region.d.ts +10 -0
- package/dist/camera/bounding_box_metering_region.js +1 -0
- package/dist/camera/camera_defaults.d.ts +0 -2
- package/dist/camera/camera_defaults.js +1 -1
- package/dist/camera/document_image_pipeline.d.ts +9 -0
- package/dist/camera/document_image_pipeline.js +1 -1
- package/dist/camera/imported_document_folder.d.ts +15 -0
- package/dist/camera/imported_document_folder.js +1 -0
- package/dist/camera/kamera_config_factory.d.ts +11 -1
- package/dist/camera/kamera_config_factory.js +1 -1
- package/dist/camera/use_smile_id_frame_stream.js +1 -1
- package/dist/camera/use_smile_id_kamera_camera_system.d.ts +46 -2
- package/dist/camera/use_smile_id_kamera_camera_system.js +1 -1
- package/dist/core/exception/use_smile_id_error_code.js +1 -1
- package/dist/core/exception/use_smile_id_network_exception.d.ts +10 -3
- package/dist/core/exception/use_smile_id_network_exception.js +1 -1
- package/dist/core/is_development_build.d.ts +6 -0
- package/dist/core/is_development_build.js +1 -0
- package/dist/core/models/config.d.ts +6 -0
- package/dist/core/models/ml_config.d.ts +1 -1
- package/dist/core/models/network_config.d.ts +4 -1
- package/dist/core/models/params.d.ts +8 -6
- package/dist/core/models/result.d.ts +11 -0
- package/dist/core/models/result.js +1 -1
- package/dist/core/perf/capture_perf_trace.d.ts +90 -0
- package/dist/core/perf/capture_perf_trace.js +1 -0
- package/dist/data/api/interceptors/logging_interceptor.js +1 -1
- package/dist/data/api/interceptors/smile_auth_interceptor.js +1 -1
- package/dist/data/api/request_capture.d.ts +16 -0
- package/dist/data/api/request_capture.js +1 -0
- package/dist/data/api/smile_id_api.d.ts +1 -1
- package/dist/data/api/smile_id_api.js +1 -1
- package/dist/data/factory/networking_factory.d.ts +3 -1
- package/dist/data/factory/networking_factory.js +1 -1
- package/dist/data/model/captured_job.d.ts +49 -0
- package/dist/data/model/captured_job.js +1 -0
- package/dist/data/model/job_request.d.ts +1 -1
- package/dist/data/model/sealed_job_request.d.ts +15 -0
- package/dist/data/model/sealed_job_request.js +1 -0
- package/dist/data/model/token_payload.d.ts +5 -7
- package/dist/data/model/token_payload.js +1 -1
- package/dist/data/model/user_details_payload.d.ts +6 -4
- package/dist/data/repository/use_smile_id_repository.d.ts +7 -0
- package/dist/data/repository/use_smile_id_repository_impl.d.ts +29 -2
- package/dist/data/repository/use_smile_id_repository_impl.js +1 -1
- package/dist/data/security/job_package_crypto.d.ts +41 -0
- package/dist/data/security/job_package_crypto.js +1 -0
- package/dist/data/security/job_package_sealer.d.ts +35 -0
- package/dist/data/security/job_package_sealer.js +1 -0
- package/dist/data/security/signing_crypto.d.ts +34 -0
- package/dist/data/security/signing_crypto.js +1 -1
- package/dist/data/util/retry_util.d.ts +9 -6
- package/dist/data/util/retry_util.js +1 -1
- package/dist/debug/selfie_preview_debug_geometry.d.ts +13 -13
- package/dist/debug/selfie_preview_debug_geometry.js +1 -1
- package/dist/debug/use_smile_id_debug.d.ts +25 -2
- package/dist/debug/use_smile_id_debug.js +1 -1
- package/dist/debug/use_smile_id_document_preview_debug_overlay.js +1 -1
- package/dist/debug/use_smile_id_selfie_preview_debug_overlay.d.ts +5 -1
- package/dist/debug/use_smile_id_selfie_preview_debug_overlay.js +1 -1
- package/dist/index.d.ts +4 -1
- package/dist/index.js +1 -1
- package/dist/l10n/strings_en.d.ts +3 -3
- package/dist/l10n/strings_en.js +2 -2
- package/dist/l10n/use_smile_id_localizations.d.ts +5 -7
- package/dist/l10n/use_smile_id_localizations.js +1 -1
- package/dist/metadata/metadata_configuration_mappers.d.ts +3 -5
- package/dist/metadata/metadata_configuration_mappers.js +1 -1
- package/dist/metadata/use_smile_id_metadata_factory.js +1 -1
- package/dist/presentation/assets/si_dark_lighting_animation.json +1 -927
- package/dist/presentation/assets/si_device_orientation_animation.json +1 -850
- package/dist/presentation/assets/si_document_green_book_hero_animation.json +1 -4740
- package/dist/presentation/assets/si_document_hero_animation.json +1 -4870
- package/dist/presentation/assets/si_document_hero_back_animation.json +1 -2122
- package/dist/presentation/assets/si_document_passport_hero_animation.json +1 -14540
- package/dist/presentation/assets/si_ess_all_directions_hero_animation.json +1 -5906
- package/dist/presentation/assets/si_ess_animation_all_directions.json +1 -5906
- package/dist/presentation/assets/si_selfie_hero_animation.json +1 -1468
- package/dist/presentation/assets/si_smile_to_capture_animation.json +1 -1412
- package/dist/presentation/components/helpers/captured_image_uri.d.ts +11 -0
- package/dist/presentation/components/helpers/captured_image_uri.js +1 -0
- package/dist/presentation/components/helpers/captured_oval_region.d.ts +40 -0
- package/dist/presentation/components/helpers/captured_oval_region.js +1 -0
- package/dist/presentation/components/helpers/document_interior_crop.d.ts +13 -2
- package/dist/presentation/components/helpers/document_interior_crop.js +1 -1
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.d.ts +35 -29
- package/dist/presentation/components/helpers/enhanced_smart_selfie_animation_frames.js +1 -1
- package/dist/presentation/components/helpers/selfie_interior_crop.js +1 -1
- package/dist/presentation/components/use_smile_id_capture_content.d.ts +5 -2
- package/dist/presentation/components/use_smile_id_capture_content.js +1 -1
- package/dist/presentation/components/use_smile_id_captured_document_image.d.ts +8 -4
- package/dist/presentation/components/use_smile_id_captured_document_image.js +1 -1
- package/dist/presentation/components/use_smile_id_captured_image_oval.d.ts +6 -0
- package/dist/presentation/components/use_smile_id_captured_image_oval.js +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.d.ts +17 -7
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_clip.js +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_direction_animation.d.ts +13 -14
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_direction_animation.js +1 -1
- package/dist/presentation/components/use_smile_id_enhanced_smart_selfie_full_animation.js +1 -1
- package/dist/presentation/components/use_smile_id_face_oval_image.js +1 -1
- package/dist/presentation/flow/analytics/unsatisfied_reasons.d.ts +14 -0
- package/dist/presentation/flow/analytics/unsatisfied_reasons.js +1 -0
- package/dist/presentation/flow/analytics/use_smile_id_analytics_event.d.ts +8 -7
- package/dist/presentation/flow/analytics/use_smile_id_analytics_event.js +1 -1
- package/dist/presentation/flow/analytics/use_smile_id_analytics_event_kind.d.ts +9 -0
- package/dist/presentation/flow/analytics/use_smile_id_analytics_event_kind.js +1 -1
- package/dist/presentation/flow/config/flow_configuration_camera.d.ts +9 -0
- package/dist/presentation/flow/config/flow_configuration_camera.js +1 -0
- package/dist/presentation/flow/dsl/builder/config_builder.d.ts +6 -0
- package/dist/presentation/flow/dsl/builder/config_builder.js +1 -1
- package/dist/presentation/flow/dsl/builder/ml_builder.d.ts +1 -7
- package/dist/presentation/flow/dsl/builder/ml_builder.js +1 -1
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.d.ts +0 -9
- package/dist/presentation/flow/dsl/use_smile_id_flow_builder.js +1 -1
- package/dist/presentation/flow/flow_navigation_manager.d.ts +39 -70
- package/dist/presentation/flow/flow_navigation_manager.js +1 -1
- package/dist/presentation/flow/flow_navigation_manager_analytics.d.ts +23 -0
- package/dist/presentation/flow/flow_navigation_manager_analytics.js +1 -0
- package/dist/presentation/flow/flow_navigation_manager_documents.d.ts +18 -0
- package/dist/presentation/flow/flow_navigation_manager_documents.js +1 -0
- package/dist/presentation/flow/flow_navigation_manager_job_request.d.ts +7 -0
- package/dist/presentation/flow/flow_navigation_manager_job_request.js +1 -0
- package/dist/presentation/flow/flow_navigation_manager_routing.d.ts +12 -0
- package/dist/presentation/flow/flow_navigation_manager_routing.js +1 -0
- package/dist/presentation/flow/flow_navigation_manager_submission.d.ts +17 -0
- package/dist/presentation/flow/flow_navigation_manager_submission.js +1 -0
- package/dist/presentation/flow/job_submission_state.d.ts +4 -0
- package/dist/presentation/flow/screen/helpers/face_session_config.d.ts +1 -1
- package/dist/presentation/flow/screen/helpers/failure_message.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_capture_screen.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_instructions_screen.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_preview_screen.js +1 -1
- package/dist/presentation/flow/screen/orchestrated_processing_screen.js +1 -1
- package/dist/presentation/flow/use_smile_id_flow.js +1 -1
- package/dist/presentation/flow/validation/flow_validator.d.ts +0 -19
- package/dist/presentation/flow/validation/flow_validator.js +1 -1
- package/dist/presentation/flow/validation/job_type_validator.js +1 -1
- package/dist/presentation/screen/helpers/capture_screen_helpers.d.ts +0 -12
- package/dist/presentation/screen/helpers/capture_screen_helpers.js +1 -1
- package/dist/presentation/screen/helpers/capture_ui_state.d.ts +33 -6
- package/dist/presentation/screen/helpers/capture_ui_state.js +1 -1
- package/dist/presentation/screen/helpers/dropped_frames.d.ts +6 -0
- package/dist/presentation/screen/helpers/dropped_frames.js +1 -0
- package/dist/presentation/screen/helpers/ess_turn_haptics.d.ts +2 -0
- package/dist/presentation/screen/helpers/ess_turn_haptics.js +1 -1
- package/dist/presentation/screen/helpers/instructions_screen_helpers.d.ts +5 -1
- package/dist/presentation/screen/helpers/instructions_screen_helpers.js +1 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.d.ts +23 -1
- package/dist/presentation/screen/helpers/use_capture_orientation_lock.js +1 -1
- package/dist/presentation/screen/helpers/use_debounced_feedback_key.d.ts +1 -1
- package/dist/presentation/screen/helpers/use_debounced_feedback_key.js +1 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.d.ts +4 -1
- package/dist/presentation/screen/use_smile_id_capture_screen.js +1 -1
- package/dist/presentation/screen/use_smile_id_consent_screen.js +1 -1
- package/dist/presentation/screen/use_smile_id_preview_screen.d.ts +3 -0
- package/dist/presentation/screen/use_smile_id_preview_screen.js +1 -1
- package/dist/presentation/screen/use_smile_id_processing_screen.d.ts +3 -0
- package/dist/presentation/screen/use_smile_id_processing_screen.js +1 -1
- package/dist/presentation/utils/locale_utils.d.ts +3 -6
- package/dist/presentation/utils/locale_utils.js +1 -1
- package/dist/testing/scenario_expectations.d.ts +7 -2
- package/dist/testing/scenario_expectations.js +1 -1
- package/dist/testing/scripted_scan_results.d.ts +2 -1
- package/dist/testing/scripted_scan_results.js +1 -1
- package/package.json +7 -7
- package/dist/presentation/flow/validation/user_details_validator.d.ts +0 -8
- package/dist/presentation/flow/validation/user_details_validator.js +0 -1
|
@@ -24,6 +24,12 @@ export declare class UseSmileIDConfigBuilder {
|
|
|
24
24
|
* submitted later when connectivity returns. Defaults to false.
|
|
25
25
|
*/
|
|
26
26
|
allowOfflineMode: boolean;
|
|
27
|
+
/**
|
|
28
|
+
* When true, the flow captures the job and hands it back through `onResult`
|
|
29
|
+
* as `{ status: "captured", job }` instead of submitting it to Smile ID.
|
|
30
|
+
* The captured files are kept on disk for you to forward and delete.
|
|
31
|
+
*/
|
|
32
|
+
skipApiSubmission: boolean;
|
|
27
33
|
/**
|
|
28
34
|
* Journey-wide "Powered by Smile ID" branding (default true); document
|
|
29
35
|
* capture never shows it.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import*as
|
|
1
|
+
"use strict";import*as i from"expo-screen-orientation";import{GlobalPrivacyControl as e}from"../../../../core/models/global_privacy_control";export class UseSmileIDConfigBuilder{enableCrashReporting=!0;enableDebugMode=!1;allowOfflineMode=!1;skipApiSubmission=!1;showAttribution=!0;globalPrivacyControl=e.OptOut;exitOrientations=i.OrientationLock.PORTRAIT_UP;build(){return Object.freeze({enableCrashReporting:this.enableCrashReporting,enableDebugMode:this.enableDebugMode,allowOfflineMode:this.allowOfflineMode,skipApiSubmission:this.skipApiSubmission,showAttribution:this.showAttribution,globalPrivacyControl:this.globalPrivacyControl,exitOrientations:this.exitOrientations})}}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { FaceAnalyzer, DocumentAnalyzer } from "@smileid/usesmileid_platform_interface";
|
|
2
|
-
import {
|
|
2
|
+
import { type FaceConfig, type FaceDetectorConfig, type FaceDetectorMode } from "@smileid/usesmileid_bridge";
|
|
3
3
|
import { CaptureType, type AnalyzerRegistry, type MLConfig } from "../../../../core/models/ml_config";
|
|
4
4
|
/**
|
|
5
5
|
* `b.ml((m) => { m.analyzers((a) => { a.forCaptureType(CaptureType.selfie, (face) => face.add(useSmileIDVisionFace)); }); })`
|
|
@@ -24,12 +24,6 @@ export declare class FaceAnalyzerScope {
|
|
|
24
24
|
add(analyzer: FaceAnalyzer): void;
|
|
25
25
|
/** @internal */
|
|
26
26
|
_analyzer?: FaceAnalyzer;
|
|
27
|
-
/**
|
|
28
|
-
* Scan-loop tuning preset (Fast / Balanced / HighQuality). Default is
|
|
29
|
-
* `Balanced`; the orchestrator lifts the field into `FaceConfig` at
|
|
30
|
-
* configure time.
|
|
31
|
-
*/
|
|
32
|
-
scanPerformanceProfile: ScanPerformanceProfile;
|
|
33
27
|
/**
|
|
34
28
|
* Face-detection preset. A token (`"performance"` / `"default"` / `"low"`)
|
|
35
29
|
* the native backend resolves to its own engine-calibrated thresholds;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{
|
|
1
|
+
"use strict";import{FaceCaptureDefaults as a}from"@smileid/usesmileid_bridge";import{CaptureType as l}from"../../../../core/models/ml_config";export class FaceAnalyzerScope{add(n){this._analyzer=n}_analyzer;detectorMode="default";faceDetectorConfig;toFaceConfig(){const n=this._analyzer;if(!n)return;const e=this.faceDetectorConfig;return{numSamples:a.numSamples,faceDetectorMode:this.detectorMode,...e?.minFillThreshold!==void 0?{minFillThreshold:e.minFillThreshold}:{},...e?.maxFillThreshold!==void 0?{maxFillThreshold:e.maxFillThreshold}:{},...e?.faceDetectorMinScore!==void 0?{faceDetectorMinScore:e.faceDetectorMinScore}:{},...e?.centerToleranceX!==void 0?{centerToleranceX:e.centerToleranceX}:{},...e?.centerToleranceY!==void 0?{centerToleranceY:e.centerToleranceY}:{},...e?.motionBlurMinIou!==void 0?{motionBlurMinIou:e.motionBlurMinIou}:{},...e?.motionBlurMinDuration!==void 0?{motionBlurMinDuration:e.motionBlurMinDuration}:{},...e?.minTopPadding!==void 0?{minTopPadding:e.minTopPadding}:{},...e?.minFaceBoundsThreshold!==void 0?{minFaceBoundsThreshold:e.minFaceBoundsThreshold}:{},...e?.maxFaceBoundsThreshold!==void 0?{maxFaceBoundsThreshold:e.maxFaceBoundsThreshold}:{},...e?.minSmileProbability!==void 0?{minSmileProbability:e.minSmileProbability}:{},analyzerFactoryKey:n.key}}}export class DocumentAnalyzerScope{add(n){this._analyzer=n}_analyzer}export class AnalyzerRegistryBuilder{_selfie;_selfieConfig;_document;forCaptureType(n,e){if(n===l.selfie){const i=new FaceAnalyzerScope;e(i),i._analyzer&&(this._selfie=i._analyzer,this._selfieConfig=i.toFaceConfig());return}const o=new DocumentAnalyzerScope;e(o),o._analyzer&&(this._document=o._analyzer)}build(){return Object.freeze({...this._selfie?{selfie:this._selfie}:{},...this._selfieConfig?{selfieConfig:this._selfieConfig}:{},...this._document?{document:this._document}:{}})}}export class UseSmileIDMLBuilder{_analyzers;analyzers(n){this._analyzers||(this._analyzers=new AnalyzerRegistryBuilder),n(this._analyzers)}build(){return Object.freeze({analyzers:this._analyzers?this._analyzers.build():Object.freeze({})})}}
|
|
@@ -191,15 +191,6 @@ export declare class UseSmileIDFlowBuilder {
|
|
|
191
191
|
* `build()`.
|
|
192
192
|
*/
|
|
193
193
|
validateResidencyDocumentVerificationParams(params: ResidencyDocumentVerificationParams): ValidationState;
|
|
194
|
-
/**
|
|
195
|
-
* Validates a `UserDetails` payload in isolation and returns a
|
|
196
|
-
* `ValidationState`, without throwing. Useful when the partner pulls
|
|
197
|
-
* user PII from a form or remote config and wants to pre-flight it
|
|
198
|
-
* before assigning to `b.userDetails`. Surfaces the same dotted-path
|
|
199
|
-
* field names (`userDetails.givenNames` etc.) that the in-build
|
|
200
|
-
* validator emits.
|
|
201
|
-
*/
|
|
202
|
-
validateUserDetails(userDetails: UserDetails): ValidationState;
|
|
203
194
|
/**
|
|
204
195
|
* Snapshot the current builder state and report the validation
|
|
205
196
|
* outcome as a [FlowBuildResult]. Returns `{kind: 'success', ...}`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{RESIDENCY_ID_TYPE as d}from"../../../core/models/params";import{UseSmileIDConfigBuilder as l}from"./builder/config_builder";import{ThemeConfigBuilder as u}from"./builder/theme_builder";import{UseSmileIDNetworkBuilder as h}from"../../../data/dsl/use_smile_id_network_builder";import{UseSmileIDMLBuilder as f}from"./builder/ml_builder";import{ScreensBuilder as P}from"./builder/screens_builder";import{IssueSeverity as D}from"../../../core/exception/issue_severity";import{runBiometricKYCParamsValidation as V,runBuilderValidation as v,runConsentValidation as _,runDocumentVerificationParamsValidation as I,runEnhancedDocumentVerificationParamsValidation as g,runEnhancedKYCParamsValidation as w,runFlowValidation as y,runResidencyDocumentVerificationParamsValidation as C
|
|
1
|
+
"use strict";import{RESIDENCY_ID_TYPE as d}from"../../../core/models/params";import{UseSmileIDConfigBuilder as l}from"./builder/config_builder";import{ThemeConfigBuilder as u}from"./builder/theme_builder";import{UseSmileIDNetworkBuilder as h}from"../../../data/dsl/use_smile_id_network_builder";import{UseSmileIDMLBuilder as f}from"./builder/ml_builder";import{ScreensBuilder as P}from"./builder/screens_builder";import{IssueSeverity as D}from"../../../core/exception/issue_severity";import{runBiometricKYCParamsValidation as V,runBuilderValidation as v,runConsentValidation as _,runDocumentVerificationParamsValidation as I,runEnhancedDocumentVerificationParamsValidation as g,runEnhancedKYCParamsValidation as w,runFlowValidation as y,runResidencyDocumentVerificationParamsValidation as C}from"../validation/flow_validator";import{ValidationState as n}from"../validation/validation_state";import{residencyIdTypeIssue as p}from"../validation/job_type_validator";import{decodeSmileIDToken as Y}from"../../../data/util/use_smile_id_token_decoder";export class UseSmileIDFlowBuilder{consentInformation;enhancedKYCParams;biometricKYCParams;documentVerificationParams;enhancedDocumentVerificationParams;residencyDocumentVerificationParams;userDetails;userId;localizations;onResult=()=>{};onAnalyticsEvent;_config;_theme;_network;_ml;_screens;config(i){this._config||(this._config=new l),i(this._config)}theme(i){this._theme=new u,i(this._theme)}network(i){this._network=new h,i(this._network)}ml(i){this._ml||(this._ml=new f),i(this._ml)}screens(i){this._screens||(this._screens=new P),i(this._screens)}validate(){return n.invalid(v(this._screens?.build().steps??[]))}validateConsent(i){return n.invalid(_(i))}validateEnhancedKYCParams(i){return n.invalid(w(i))}validateBiometricKYCParams(i){return n.invalid(V(i))}validateDocumentVerificationParams(i){return n.invalid(I(i))}validateEnhancedDocumentVerificationParams(i){return n.invalid(g(i))}validateResidencyDocumentVerificationParams(i){const e=i.idType.trim()!==""&&i.idType!==d?[p()]:[];return n.invalid([...C(i),...e])}build(){const i=this._screens?.build(),e=this._network?.build(),a=this._ml?.build(),s=this._config?.build(),m=K(s?.allowOfflineMode,e),o=y({steps:i?.steps??[],network:e,ml:a,consentInformation:this.consentInformation,enhancedKYCParams:this.enhancedKYCParams,biometricKYCParams:this.biometricKYCParams,documentVerificationParams:this.documentVerificationParams,enhancedDocumentVerificationParams:this.enhancedDocumentVerificationParams,residencyDocumentVerificationParams:this.residencyDocumentVerificationParams,userDetails:this.userDetails,userId:this.userId,tokenPayload:m}),c=n.invalid(o);if(!c.valid)return{kind:"invalid",validation:c};for(const t of o)t.severity===D.warning&&(console.warn(`[UseSmileIDFlowBuilder] ${t.message}`),t.suggestedFix&&console.warn(`[UseSmileIDFlowBuilder] Suggested fix: ${t.suggestedFix}`));if(!i)throw new Error("UseSmileIDFlowBuilder: internal invariant violated \u2014 screens missing after validation passed.");return{kind:"success",configuration:Object.freeze({...this.consentInformation?{consentInformation:this.consentInformation}:{},...this.enhancedKYCParams?{enhancedKYCParams:this.enhancedKYCParams}:{},...this.biometricKYCParams?{biometricKYCParams:this.biometricKYCParams}:{},...this.documentVerificationParams?{documentVerificationParams:this.documentVerificationParams}:{},...this.enhancedDocumentVerificationParams?{enhancedDocumentVerificationParams:this.enhancedDocumentVerificationParams}:{},...this.residencyDocumentVerificationParams?{residencyDocumentVerificationParams:this.residencyDocumentVerificationParams}:{},...this.userDetails?{userDetails:this.userDetails}:{},...this.userId?{userId:this.userId}:{},...s?{config:s}:{},...this._theme?{theme:this._theme.build()}:{},...e?{network:e}:{},...a?{ml:a}:{},screens:i,...this.localizations?{localizations:this.localizations}:{},onResult:this.onResult,...this.onAnalyticsEvent?{onAnalyticsEvent:this.onAnalyticsEvent}:{}})}}}function K(r,i){if(r)return;const e=i?.config?.token;if(!(!e||e.length===0))return Y(e)?.tokenPayload}
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import type { SelfieCaptureGeometry } from "../components/helpers/captured_oval_region";
|
|
1
2
|
import type { ScreenSpec } from "./dsl/builder/screens_builder";
|
|
2
3
|
import type { FlowConfigurationSnapshot } from "./dsl/use_smile_id_flow_builder";
|
|
3
4
|
import type { JobSubmissionState } from "./job_submission_state";
|
|
4
5
|
import type { UseSmileIDRepository } from "../../data/repository/use_smile_id_repository";
|
|
5
6
|
import type { ConsentInformation } from "../../core/models/params";
|
|
6
7
|
import { type DocumentType } from "../../core/models/document_type";
|
|
8
|
+
import type { CapturedJob } from "../../data/model/captured_job";
|
|
7
9
|
import type { JobSubmissionResponse } from "../../data/model/job_submission_response";
|
|
8
|
-
import {
|
|
10
|
+
import type { UseSmileIDAnalyticsEventKind } from "./analytics/use_smile_id_analytics_event_kind";
|
|
9
11
|
import { type MetadataProvider } from "../../metadata/use_smile_id_metadata_factory";
|
|
10
|
-
import {
|
|
12
|
+
import type { DocumentImageOrigin } from "../../metadata/document_image_origin";
|
|
11
13
|
import type { CaptureTelemetry } from "../screen/use_smile_id_capture_screen";
|
|
12
14
|
import type { SdkConfig } from "../../data/model/sdk_config";
|
|
13
15
|
import { DocumentSide } from "@smileid/usesmileid_bridge";
|
|
@@ -37,6 +39,11 @@ export type FlowExitReason = {
|
|
|
37
39
|
} | {
|
|
38
40
|
readonly kind: "failed";
|
|
39
41
|
readonly error: unknown;
|
|
42
|
+
}
|
|
43
|
+
/** `skipApiSubmission`: the assembled job was handed to the partner, never submitted. */
|
|
44
|
+
| {
|
|
45
|
+
readonly kind: "captured";
|
|
46
|
+
readonly job: CapturedJob;
|
|
40
47
|
};
|
|
41
48
|
export type FlowExitHandler = (reason: FlowExitReason) => void;
|
|
42
49
|
export type FlowNavigationManagerOptions = {
|
|
@@ -58,6 +65,14 @@ export type FlowNavigationManagerOptions = {
|
|
|
58
65
|
*/
|
|
59
66
|
readonly metadataProvider?: MetadataProvider;
|
|
60
67
|
};
|
|
68
|
+
/**
|
|
69
|
+
* Holds the flow's state, navigation and completion. Routing, document sides,
|
|
70
|
+
* request assembly, submission and analytics live in the
|
|
71
|
+
* `flow_navigation_manager_*` modules, as functions that take the manager
|
|
72
|
+
* first; the public methods here delegate to them. Those functions reach the
|
|
73
|
+
* private state by element access (`manager["_captured"]`), which TypeScript
|
|
74
|
+
* still type-checks and the published types keep private.
|
|
75
|
+
*/
|
|
61
76
|
export declare class FlowNavigationManager {
|
|
62
77
|
/**
|
|
63
78
|
* Navigation stack and source of truth — top is the active screen.
|
|
@@ -98,6 +113,9 @@ export declare class FlowNavigationManager {
|
|
|
98
113
|
private readonly _onExit;
|
|
99
114
|
private _disposed;
|
|
100
115
|
private _submissionResponse;
|
|
116
|
+
private _capturedJob;
|
|
117
|
+
/** Set once `onExit` has been called: a hand-over still being assembled then delivers nothing. */
|
|
118
|
+
private _flowEnded;
|
|
101
119
|
/**
|
|
102
120
|
* Decoded `sdk_config` JWT claim, resolved once at construction.
|
|
103
121
|
* `undefined` for offline mode / no token / no valid claim — SDK
|
|
@@ -131,8 +149,10 @@ export declare class FlowNavigationManager {
|
|
|
131
149
|
get configuration(): FlowConfigurationSnapshot;
|
|
132
150
|
/** Whether any selfie step enabled Enhanced Smart Selfie (drives the instructions hero swap and oval-progress suppression). */
|
|
133
151
|
get enhancedLivenessEnabled(): boolean;
|
|
134
|
-
/** Document type from the flow's document capture step, if any
|
|
152
|
+
/** Document type from the flow's document capture step, if any. */
|
|
135
153
|
get documentType(): DocumentType | undefined;
|
|
154
|
+
/** Document type of the next capture; `undefined` when it is a selfie. */
|
|
155
|
+
get instructionsDocumentType(): DocumentType | undefined;
|
|
136
156
|
/**
|
|
137
157
|
* Resolved document capture-frame aspect ratio (width / height), shared by
|
|
138
158
|
* capture, preview, and processing. Precedence: type `knownAspectRatio` →
|
|
@@ -167,10 +187,20 @@ export declare class FlowNavigationManager {
|
|
|
167
187
|
navigateBack(): void;
|
|
168
188
|
/** Reset the path to the first screen (flow restart after terminal failure, manager kept alive). */
|
|
169
189
|
navigateToStart(): void;
|
|
170
|
-
/**
|
|
190
|
+
/**
|
|
191
|
+
* Exit the flow with a partner-supplied reason (processing onExit, consent denied, etc.).
|
|
192
|
+
* A `captured` reason is ignored: only the skip-submission hand-over produces it.
|
|
193
|
+
*/
|
|
171
194
|
exit(reason?: FlowExitReason): void;
|
|
172
195
|
get captured(): CapturedArtifacts;
|
|
196
|
+
/** The job handed to the partner by the skip-submission path; `undefined` until then and in every flow that submits. */
|
|
197
|
+
get capturedJob(): CapturedJob | undefined;
|
|
173
198
|
setCapturedSelfie(selfiePath: string, livenessPaths: readonly string[]): void;
|
|
199
|
+
/** @internal What the selfie capture screen laid out; undefined before a selfie was captured. */
|
|
200
|
+
get selfieCaptureGeometry(): SelfieCaptureGeometry | undefined;
|
|
201
|
+
private _selfieCaptureGeometry;
|
|
202
|
+
/** @internal Keeps the selfie capture screen's geometry for the review screens. */
|
|
203
|
+
recordSelfieCaptureGeometry(geometry: SelfieCaptureGeometry | undefined): void;
|
|
174
204
|
setCapturedFrontDocument(path: string, borderFraction?: number): void;
|
|
175
205
|
setCapturedBackDocument(path: string, borderFraction?: number): void;
|
|
176
206
|
/**
|
|
@@ -182,8 +212,6 @@ export declare class FlowNavigationManager {
|
|
|
182
212
|
supportingDocumentSide(): DocumentSide | undefined;
|
|
183
213
|
/** Whether the configured document capture asks for a back side. */
|
|
184
214
|
documentCapturesBack(): boolean;
|
|
185
|
-
/** Captured path for {@link supportingDocumentSide}, or undefined when absent or not yet captured. */
|
|
186
|
-
private _capturedSupportingDocument;
|
|
187
215
|
/** The document image the capture screen should handle now: front until it exists, then the supporting image. */
|
|
188
216
|
currentDocumentCaptureSide(): DocumentSide;
|
|
189
217
|
setCapturedVisaDocument(path: string, borderFraction?: number): void;
|
|
@@ -200,7 +228,6 @@ export declare class FlowNavigationManager {
|
|
|
200
228
|
documentBorderFraction(side: DocumentSide): number;
|
|
201
229
|
/** The hidden border of the document under review, {@link currentDocumentPreviewPath}. */
|
|
202
230
|
currentDocumentPreviewBorderFraction(): number;
|
|
203
|
-
private _setDocumentBorderFraction;
|
|
204
231
|
/**
|
|
205
232
|
* Discard the side under review for re-capture: the back if captured,
|
|
206
233
|
* else the front (which also un-skips the back). Does not navigate.
|
|
@@ -220,17 +247,6 @@ export declare class FlowNavigationManager {
|
|
|
220
247
|
recordSelfieCaptureTelemetry(telemetry: CaptureTelemetry): void;
|
|
221
248
|
/** Records per-side document capture telemetry at each side's completion. */
|
|
222
249
|
recordDocumentCaptureTelemetry(side: DocumentSide, telemetry: CaptureTelemetry): void;
|
|
223
|
-
private _captureCameraName;
|
|
224
|
-
/** Per-image document origin wire entries (front, back, visa; omitted when unset). */
|
|
225
|
-
private _documentImageOriginEntries;
|
|
226
|
-
/**
|
|
227
|
-
* Capture telemetry + image-property wire entries. Durations and retries keep
|
|
228
|
-
* a meaningful 0 (capture ran) and are omitted only when that capture type
|
|
229
|
-
* never ran. Color depth / pixel config are emitted for each present capture;
|
|
230
|
-
* document sizes when measured.
|
|
231
|
-
*/
|
|
232
|
-
private _captureTelemetryEntries;
|
|
233
|
-
private _precedingStepIsDocumentCapture;
|
|
234
250
|
setConsent(info: ConsentInformation): void;
|
|
235
251
|
get jobSubmissionState(): JobSubmissionState;
|
|
236
252
|
/**
|
|
@@ -244,70 +260,23 @@ export declare class FlowNavigationManager {
|
|
|
244
260
|
* defeat `beginSubmissionIfNeeded()`'s single-flight guard.
|
|
245
261
|
*/
|
|
246
262
|
retrySubmission(): void;
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Build the request, dispatch via repository, update state. Errors
|
|
250
|
-
* from `_assembleJob` (missing captures / bad job type) map to the
|
|
251
|
-
* `failure` state rather than propagating as unhandled rejections.
|
|
252
|
-
*/
|
|
253
|
-
private _submit;
|
|
254
|
-
/**
|
|
255
|
-
* Build a typed `JobRequest` from `jobType` + captured artifacts.
|
|
256
|
-
* Throws a descriptive message when a required capture is missing.
|
|
257
|
-
*/
|
|
258
|
-
private _assembleJob;
|
|
259
|
-
private _requireSelfie;
|
|
260
|
-
/**
|
|
261
|
-
* The ID field to submit, blanked — so the wire omits its part — when
|
|
262
|
-
* the token binds it. The server injects the token-bound value and
|
|
263
|
-
* rejects a request whose body contradicts it, so a bound field is
|
|
264
|
-
* never sent, whatever the builder was given. An unbound blank field
|
|
265
|
-
* throws here, as a missing `userDetails` does, rather than failing on
|
|
266
|
-
* the server — so a blank reaching the API is always a token-bound one.
|
|
267
|
-
*/
|
|
268
|
-
private _unlessTokenBinds;
|
|
269
|
-
/** The KYC params' three ID fields, each one the token binds blanked. */
|
|
270
|
-
private _kycIdFieldsToSubmit;
|
|
271
|
-
/**
|
|
272
|
-
* Resolve `b.userDetails` for the wire. May legitimately return
|
|
273
|
-
* `undefined` when the token binds every required field
|
|
274
|
-
* (`given_names`, `last_name`, and a contact field) — the
|
|
275
|
-
* `user_details` part is then omitted and the server injects the
|
|
276
|
-
* token's values. Otherwise throws exactly as before token support.
|
|
277
|
-
*/
|
|
278
|
-
private _requireUserDetails;
|
|
263
|
+
/** Emit terminal `flow_completed` (completed/failed only; not cancelled), then exit via `onExit`. */
|
|
279
264
|
/**
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
265
|
+
* Replace the captured artifacts, deleting any imported document the new set
|
|
266
|
+
* drops: each import has its own folder, so a re-import never overwrites the
|
|
267
|
+
* one it replaces.
|
|
283
268
|
*/
|
|
284
|
-
private
|
|
285
|
-
private _requireFrontDocument;
|
|
286
|
-
/** Capture-artifact fields shared by both document request variants. */
|
|
287
|
-
private _documentRequestFields;
|
|
288
|
-
/** The captured visa page, or undefined when the residency flow has not reached it. */
|
|
289
|
-
private _capturedVisaDocument;
|
|
290
|
-
/** Emit terminal `flow_completed` (completed/failed only; not cancelled), then exit via `onExit`. */
|
|
269
|
+
private _setCaptured;
|
|
291
270
|
/** Captured images are removed at every terminal unless offline mode keeps them for a later submission. */
|
|
292
271
|
private _deleteCapturedFiles;
|
|
293
272
|
private _finishFlow;
|
|
294
273
|
/** Emits a capture-layer event, such as a selfie session restart, with the flow's `session_id` + `timestamp` enrichment. */
|
|
295
274
|
logAnalyticsEvent(event: UseSmileIDAnalyticsEventKind): void;
|
|
296
|
-
private _logKind;
|
|
297
|
-
/** Forward a lifecycle event to `onAnalyticsEvent`, adding `session_id` + `timestamp`. No-op without a callback. */
|
|
298
|
-
private _logEvent;
|
|
299
275
|
private _jobType;
|
|
300
|
-
private _screenAnalyticsName;
|
|
301
276
|
/** Subscribe to state changes; returns an unsubscribe (safe after `dispose()`). */
|
|
302
277
|
subscribe(listener: Listener): () => void;
|
|
303
278
|
/** Tear down — drop listeners, make methods no-ops (orchestrator's useEffect cleanup). */
|
|
304
279
|
dispose(): void;
|
|
305
|
-
/**
|
|
306
|
-
* Expected liveness image count: ESS uses its fixed count (head-turn
|
|
307
|
-
* flow self-manages); else the token's livenessImageCount override;
|
|
308
|
-
* else the ScanPerformanceProfile default (`numSamples - 1`).
|
|
309
|
-
*/
|
|
310
|
-
private _expectedLivenessImageCount;
|
|
311
280
|
/**
|
|
312
281
|
* Decode the partner JWT into its claims (`sdk_config`, `partner_id`). `undefined` for offline
|
|
313
282
|
* mode, no token, or an unparseable token — SDK defaults apply in those cases.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{File as v}from"expo-file-system";import{JobType as o}from"../../core/models/job_type";import{CaptureType as p}from"../../core/models/ml_config";import{defaultFrameAspectRatio as D}from"../../core/models/document_type";import{MissingJobTypeException as b,MissingRequiredFieldException as h}from"../../core/exception/job_validation_exceptions";import{InvalidFieldValueException as P}from"../../core/exception/invalid_field_value_exception";import{UseSmileIDAnalyticsParamKeys as g,UseSmileIDAnalyticsScreenNames as _}from"./analytics/use_smile_id_analytics_event";import{encodeAnalyticsEventKind as I}from"./analytics/use_smile_id_analytics_event_kind";import{UseSmileIDMetadataFactory as T}from"../../metadata/use_smile_id_metadata_factory";import{DOCUMENT_BACK_IMAGE_ORIGIN_KEY as C,DOCUMENT_FRONT_IMAGE_ORIGIN_KEY as w,DOCUMENT_VISA_IMAGE_ORIGIN_KEY as E}from"../../metadata/document_image_origin";import{configurationMetadataEntries as F}from"../../metadata/metadata_configuration_mappers";import{CAPTURE_IMAGE_COLOR_DEPTH as k,CAPTURE_IMAGE_PIXEL_CONFIG as S}from"../../metadata/captured_image_properties";import{numSamplesOverride as B}from"../../data/model/sdk_config";import{decodeSmileIDToken as N}from"../../data/util/use_smile_id_token_decoder";import{isIdFieldBoundByToken as x,isTokenConsentComplete as y,bindsRequiredUserDetails as j}from"../../data/model/token_payload";import{isUserDetailsPayloadEmpty as A,userDetailsPayloadFrom as V}from"../../data/model/user_details_payload";import{DocumentSide as n,EnhancedSmartSelfieConfig as O}from"@smileid/usesmileid_bridge";import{ScanPerformanceProfile as K}from"@smileid/usesmileid_bridge";const q=Object.freeze({granted:!1,grantedAt:"",noticeLanguage:"",noticePrivacyPolicyUrl:""});export class FlowNavigationManager{_navigationPath=[];_captured={livenessPaths:[]};_documentBackSkipped=!1;_documentBorderFractions=new Map;_documentImageOrigins=new Map;_selfieCaptureTelemetry;_documentCaptureTelemetry=new Map;_cameraName;_devicePositions=[];_deviceMovementDetected=null;_jobSubmissionState={kind:"notAttempted"};_listeners=new Set;_steps;_configuration;_repository;_metadataProvider;_onExit;_disposed=!1;_submissionResponse;resolvedSdkConfig;_resolvedPartnerId;_resolvedTokenPayload;get partnerId(){const e=this._resolvedPartnerId;return e&&e.length>0?e:this._configuration.network?.config?.partnerConfig?.partnerId??""}_sessionId;_submissionAttemptCount=0;constructor(e){this._configuration=e.configuration,this._onExit=e.onExit,this._repository=e.repository,this._metadataProvider=e.metadataProvider??new T,this._sessionId=this._metadataProvider.sessionId;const t=FlowNavigationManager._decodeToken(e.configuration);this.resolvedSdkConfig=t?.sdkConfig,this._resolvedPartnerId=t?.partnerId,this._resolvedTokenPayload=t?.tokenPayload;const i=e.configuration.screens.steps;this._steps=y(t?.tokenPayload?.consent)?i.filter(c=>c.kind!=="consent"):i;const s=this._steps[0];s&&(this._navigationPath=[s]),this._logKind({kind:"flowStarted",jobType:this._jobType()}),s&&this._logKind({kind:"screenViewed",screen:this._screenAnalyticsName(s)})}get configuration(){return this._configuration}get enhancedLivenessEnabled(){return this._steps.some(e=>e.kind==="capture"&&e.config.selfieConfig?.enableEnhancedLiveness===!0)}get documentType(){for(const e of this._steps)if(e.kind==="capture"&&e.config.captureType===p.document)return e.config.documentConfig?.documentType}get documentFrameAspectRatio(){for(const e of this._steps)if(e.kind==="capture"&&e.config.captureType===p.document){const t=e.config.documentConfig;return t?.resolvedAspectRatio??D(t?.documentType?.orientation??"Landscape")}}get navigationPath(){return this._navigationPath}get currentScreen(){return this._navigationPath[this._navigationPath.length-1]}get currentDepth(){return this._navigationPath.length-1}get isFirstScreen(){return this._navigationPath.length<=1}get isLastScreen(){return this.getNextScreen()===void 0}getNextScreen(){const e=this.currentScreen;if(!e)return;const t=this._steps.indexOf(e);if(!(t<0)){if(e.kind==="preview"&&this._precedingStepIsDocumentCapture(t)&&this.supportingDocumentSide()!==void 0&&this._capturedSupportingDocument()===void 0&&!this._documentBackSkipped){const i=this._steps[t-1];if(i!==void 0)return i}return e.kind==="capture"&&e.config.captureType===p.document&&this._documentBackSkipped&&this._steps[t+1]?.kind==="preview"?this._steps[t+2]:e.kind==="capture"&&e.config.captureType===p.document&&this.supportingDocumentSide()!==void 0&&this._captured.frontDocumentPath!==void 0&&this._capturedSupportingDocument()===void 0&&!this._documentBackSkipped&&!this.documentPreviewFollowsCapture()?e:this._steps[t+1]}}navigateToNext(){if(this._disposed)return;const e=this.getNextScreen();if(!e){const t=this._jobSubmissionState;if(this._submissionResponse){this._finishFlow({kind:"completed",job:this._submissionResponse});return}if(t.kind==="failure"){this._finishFlow({kind:"failed",error:t.error});return}const i=t.kind==="success"?t.response:{userId:"",jobId:"",status:"",message:""};this._finishFlow({kind:"completed",job:i});return}this._navigationPath=[...this._navigationPath,e],this._logKind({kind:"screenViewed",screen:this._screenAnalyticsName(e)}),e.kind==="processing"&&this._jobSubmissionState.kind==="notAttempted"&&this._repository!==void 0&&(this._jobSubmissionState={kind:"loading"}),this._notify(),e.kind==="processing"&&this._jobSubmissionState.kind==="loading"&&this._repository!==void 0&&setTimeout(()=>{this._disposed||this._submit()},0)}navigateBack(){if(!this._disposed){if(this.isFirstScreen){this._onExit({kind:"cancelled"});return}this._logKind({kind:"retakeRequested"}),this._navigationPath=this._navigationPath.slice(0,-1),this._notify()}}navigateToStart(){if(this._disposed)return;const e=this._steps[0];this._navigationPath=e?[e]:[],this._notify()}exit(e={kind:"cancelled"}){this._disposed||this._finishFlow(e)}get captured(){return this._captured}setCapturedSelfie(e,t){this._disposed||(this._captured={...this._captured,selfiePath:e,livenessPaths:Object.freeze([...t])},this._logKind({kind:"selfieCaptured",livenessImageCount:t.length}),this._notify())}setCapturedFrontDocument(e,t=0){if(this._disposed)return;const i={...this._captured,frontDocumentPath:e};delete i.backDocumentPath,delete i.visaDocumentPath;for(const s of[n.Back,n.Visa])this._documentImageOrigins.delete(s),this._documentCaptureTelemetry.delete(s),this._documentBorderFractions.delete(s);this._setDocumentBorderFraction(n.Front,t),this._captured=i,this._logKind({kind:"documentCaptured",side:n.Front}),this._notify()}setCapturedBackDocument(e,t=0){this._disposed||(this._captured={...this._captured,backDocumentPath:e},this._setDocumentBorderFraction(n.Back,t),this._logKind({kind:"documentCaptured",side:n.Back}),this._notify())}supportingDocumentSide(){if(this._configuration.network?.config?.jobType===o.residencyDocumentVerification)return n.Visa;for(const e of this._steps)if(e.kind==="capture"&&e.config.captureType===p.document){const t=e.config.documentConfig;return t?.documentType?.hasBackSide===!0&&(t?.captureBothSides??!1)?n.Back:void 0}}documentCapturesBack(){return this.supportingDocumentSide()===n.Back}_capturedSupportingDocument(){switch(this.supportingDocumentSide()){case n.Visa:return this._captured.visaDocumentPath;case n.Back:return this._captured.backDocumentPath;default:return}}currentDocumentCaptureSide(){return this._captured.frontDocumentPath===void 0?n.Front:this.supportingDocumentSide()??n.Back}setCapturedVisaDocument(e,t=0){this._disposed||(this._captured={...this._captured,visaDocumentPath:e},this._setDocumentBorderFraction(n.Visa,t),this._logKind({kind:"documentCaptured",side:n.Visa}),this._notify())}documentPreviewFollowsCapture(){const e=this._steps.findIndex(t=>t.kind==="capture"&&t.config.captureType===p.document);return e<0?!1:this._steps[e+1]?.kind==="preview"}currentPreviewIsDocument(){const e=this.currentScreen;return!e||e.kind!=="preview"?!1:this._precedingStepIsDocumentCapture(this._steps.indexOf(e))}currentDocumentPreviewPath(){return this._capturedSupportingDocument()??this._captured.frontDocumentPath}documentBorderFraction(e){return this._documentBorderFractions.get(e)??0}currentDocumentPreviewBorderFraction(){const e=this.supportingDocumentSide();return e!==void 0&&this._capturedSupportingDocument()!==void 0?this.documentBorderFraction(e):this.documentBorderFraction(n.Front)}_setDocumentBorderFraction(e,t){Number.isFinite(t)&&t>0?this._documentBorderFractions.set(e,t):this._documentBorderFractions.delete(e)}retakeCurrentDocumentSide(){if(this._disposed)return;const e={...this._captured},t=this.supportingDocumentSide();t!==void 0&&this._capturedSupportingDocument()!==void 0?(t===n.Visa?delete e.visaDocumentPath:delete e.backDocumentPath,this._documentImageOrigins.delete(t),this._documentCaptureTelemetry.delete(t),this._documentBorderFractions.delete(t)):(delete e.frontDocumentPath,this._documentImageOrigins.delete(n.Front),this._documentBorderFractions.delete(n.Front),this._documentBackSkipped=!1),this._captured=e,this._notify()}skipDocumentBack(){this._disposed||this.supportingDocumentSide()!==n.Visa&&(this._documentBackSkipped=!0,this._notify())}recordDocumentImageOrigin(e,t){this._disposed||this._documentImageOrigins.set(e,t)}recordSelfieCaptureTelemetry(e){this._disposed||(this._selfieCaptureTelemetry=e,this._captureCameraName(e))}recordDocumentCaptureTelemetry(e,t){this._disposed||(this._documentCaptureTelemetry.set(e,t),this._captureCameraName(t))}_captureCameraName(e){e.cameraName&&(this._cameraName=e.cameraName),e.devicePositions.length>0&&(this._devicePositions=e.devicePositions,this._deviceMovementDetected=e.deviceMovementDetected)}_documentImageOriginEntries(){const e=[],t=this._documentImageOrigins.get(n.Front);t!==void 0&&e.push({name:w,value:t});const i=this._documentImageOrigins.get(n.Back);i!==void 0&&e.push({name:C,value:i});const s=this._documentImageOrigins.get(n.Visa);return s!==void 0&&e.push({name:E,value:s}),e}_captureTelemetryEntries(){const e=[],t=(c,u)=>e.push({name:c,value:u}),i=this._selfieCaptureTelemetry;i&&(t("selfie_capture_duration_ms",String(i.durationMs)),t("selfie_capture_retries",String(i.retries))),this._captured.selfiePath!==void 0&&(t("selfie_image_color_depth",String(k)),t("selfie_image_pixel_config",S)),this._cameraName&&t("camera_name",this._cameraName),this._devicePositions.length>0&&(t("device_positions",JSON.stringify(this._devicePositions)),this._deviceMovementDetected!==null&&t("device_movement_detected",String(this._deviceMovementDetected)));const s=c=>{switch(c){case n.Back:return"back";case n.Visa:return"visa";default:return"front"}};for(const c of[n.Front,n.Back,n.Visa]){const u=s(c),m=this._documentCaptureTelemetry.get(c);m&&(t(`document_${u}_capture_duration_ms`,String(m.durationMs)),t(`document_${u}_capture_retries`,String(m.retries)),t(`document_${u}_image_color_depth`,String(k)),t(`document_${u}_image_pixel_config`,S))}return e}_precedingStepIsDocumentCapture(e){const t=this._steps[e-1];return t?.kind==="capture"&&t.config.captureType===p.document}setConsent(e){this._disposed||(this._captured={...this._captured,consentInformation:e},this._logKind({kind:"consentCaptured"}),this._notify())}get jobSubmissionState(){return this._jobSubmissionState}beginSubmissionIfNeeded(){this._disposed||this._jobSubmissionState.kind==="notAttempted"&&this._submit()}retrySubmission(){this._disposed||this._jobSubmissionState.kind!=="loading"&&(this._setSubmissionState({kind:"notAttempted"}),this.beginSubmissionIfNeeded())}_setSubmissionState(e){this._disposed||(this._jobSubmissionState=e,this._notify())}async _submit(){if(!this._repository){this._setSubmissionState({kind:"failure",error:new Error("Job submission not configured \u2014 no network/repository was supplied to <UseSmileIDBuilder>. Call `b.network((n) => n.config((c) => { c.token = ...; c.partnerConfig((p) => { p.partnerId = ...; }); }))`.")});return}let e;try{e=this._assembleJob()}catch(i){this._setSubmissionState({kind:"failure",error:i instanceof Error?i:new Error(String(i))});return}this._setSubmissionState({kind:"loading"}),this._submissionAttemptCount+=1,this._logKind({kind:"jobSubmitted",jobType:this._jobType(),attempt:this._submissionAttemptCount});const t=await this._repository.submit(e,this.resolvedSdkConfig);if(!this._disposed){if(t.status==="success")this._submissionResponse=t.value,this._setSubmissionState({kind:"success",response:t.value});else if(t.status==="failure"){const i=t.error instanceof Error?t.error:new Error(String(t.error));this._setSubmissionState({kind:"failure",error:i})}}}_assembleJob(){const e=this._configuration,t=e.network?.config?.jobType??o.unknown,i=y(this._resolvedTokenPayload?.consent)?void 0:this._captured.consentInformation??e.consentInformation??q,s=i!==void 0?{consent:i}:{},c=this._metadataProvider.make(this.resolvedSdkConfig),u=[...this._documentImageOriginEntries(),...this._captureTelemetryEntries(),...F(e)],m=c.withAdditionalEntries(u);switch(t){case o.smartSelfieEnrollment:{const r=this._requireSelfie(),a=this._requireUserDetails(e);return{jobType:o.smartSelfieEnrollment,selfieImage:r.selfiePath,livenessImages:r.livenessPaths,...a!==void 0?{userDetails:a}:{},...s,metadata:m,enhanced:!1,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.smartSelfieAuthentication:{const r=this._requireSelfie(),a=this._requireUserDetails(e),d=this._requireUserId(e);return{jobType:o.smartSelfieAuthentication,selfieImage:r.selfiePath,livenessImages:r.livenessPaths,...a!==void 0?{userDetails:a}:{},userId:d,...s,metadata:m,enhanced:!1,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.biometricKyc:{const r=this._requireSelfie(),a=e.biometricKYCParams;if(!a)throw new h({fieldName:"biometricKYCParams"});const d=this._requireUserDetails(e);return{jobType:o.biometricKyc,selfieImage:r.selfiePath,livenessImages:r.livenessPaths,params:{...a,...this._kycIdFieldsToSubmit(a)},...d!==void 0?{userDetails:d}:{},...s,metadata:m,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.documentVerification:{const r=this._requireSelfie(),a=this._requireFrontDocument(),d=e.documentVerificationParams;if(!d)throw new h({fieldName:"documentVerificationParams"});const f=this._requireUserDetails(e);return{jobType:o.documentVerification,...this._documentRequestFields(r,a),country:this._unlessTokenBinds(d.country,"country"),...d.idType?{idType:this._unlessTokenBinds(d.idType,"idType")}:{},...f!==void 0?{userDetails:f}:{},...s,metadata:m,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.enhancedDocumentVerification:{const r=this._requireSelfie(),a=this._requireFrontDocument(),d=e.enhancedDocumentVerificationParams;if(!d)throw new h({fieldName:"enhancedDocumentVerificationParams"});const f=this._requireUserDetails(e);return{jobType:o.enhancedDocumentVerification,...this._documentRequestFields(r,a),country:this._unlessTokenBinds(d.country,"country"),idType:this._unlessTokenBinds(d.idType,"idType"),...f!==void 0?{userDetails:f}:{},...s,metadata:m,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.residencyDocumentVerification:{const r=this._requireSelfie(),a=this._requireFrontDocument(),d=e.residencyDocumentVerificationParams;if(!d)throw new h({fieldName:"residencyDocumentVerificationParams"});const f=this._capturedVisaDocument();if(!f)throw new h({fieldName:"visaDocument"});const l=this._requireUserDetails(e);return{jobType:o.residencyDocumentVerification,selfieImage:r.selfiePath,livenessImages:r.livenessPaths,frontDocument:a,visaDocument:f,country:this._unlessTokenBinds(d.country,"country"),idType:this._unlessTokenBinds(d.idType,"idType"),...l!==void 0?{userDetails:l}:{},...s,metadata:m,expectedLivenessImageCount:this._expectedLivenessImageCount()}}case o.enhancedKyc:{const r=e.enhancedKYCParams;if(!r)throw new h({fieldName:"enhancedKYCParams"});const a=this._requireUserDetails(e);return{jobType:o.enhancedKyc,params:{...r,...this._kycIdFieldsToSubmit(r)},...a!==void 0?{userDetails:a}:{},...s,metadata:m}}case o.bvn:throw new P({fieldName:"jobType",reason:"BVN submission is not yet supported"});case o.unknown:default:throw new b}}_requireSelfie(){const{selfiePath:e,livenessPaths:t}=this._captured;if(!e)throw new h({fieldName:"selfieImage"});return{selfiePath:e,livenessPaths:t}}_unlessTokenBinds(e,t){if(x(this._resolvedTokenPayload,t))return"";if(!e.trim())throw new h({fieldName:t});return e}_kycIdFieldsToSubmit(e){return{idType:this._unlessTokenBinds(e.idType,"idType"),idNumber:this._unlessTokenBinds(e.idNumber,"idNumber"),country:this._unlessTokenBinds(e.country,"country")}}_requireUserDetails(e){const t=e.userDetails;if(!t){if(j(this._resolvedTokenPayload))return;throw new h({fieldName:"userDetails"})}const i=V(t,this._resolvedTokenPayload);return A(i)?void 0:i}_requireUserId(e){const t=e.userId?.trim();if(!t)throw new h({fieldName:"userId"});return t}_requireFrontDocument(){const{frontDocumentPath:e}=this._captured;if(!e)throw new h({fieldName:"frontDocument"});return e}_documentRequestFields(e,t){const{backDocumentPath:i}=this._captured;return{selfieImage:e.selfiePath,livenessImages:e.livenessPaths,frontDocument:t,...i?{backDocument:i}:{}}}_capturedVisaDocument(){return this._captured.visaDocumentPath}_deleteCapturedFiles(){if(this._configuration.config?.allowOfflineMode)return;const{selfiePath:e,livenessPaths:t,frontDocumentPath:i,backDocumentPath:s}=this._captured;for(const c of[e,...t,i,s])if(c)try{const u=new v(c);u.exists&&u.delete()}catch{}}_finishFlow(e){this._deleteCapturedFiles(),e.kind==="completed"?this._logKind(e.job.jobId?{kind:"flowCompletedSuccess",jobId:e.job.jobId}:{kind:"flowCompletedSuccess"}):e.kind==="failed"&&this._logKind({kind:"flowCompletedFailure",errorMessage:e.error instanceof Error?e.error.message:String(e.error)}),this._onExit(e)}logAnalyticsEvent(e){this._disposed||this._logKind(e)}_logKind(e){const{type:t,extras:i}=I(e);this._logEvent(t,i)}_logEvent(e,t={}){const i=this._configuration.onAnalyticsEvent;i&&i({type:e,extras:{...t,[g.sessionId]:this._sessionId,[g.timestamp]:String(Date.now())}})}_jobType(){return this._configuration.network?.config?.jobType??o.unknown}_screenAnalyticsName(e){return{consent:_.consent,instructions:_.instructions,capture:_.capture,preview:_.preview,processing:_.processing}[e.kind]}subscribe(e){return this._listeners.add(e),()=>{this._listeners.delete(e)}}dispose(){this._disposed=!0,this._listeners.clear()}_expectedLivenessImageCount(){if(this.enhancedLivenessEnabled)return O.EXPECTED_LIVENESS_IMAGE_COUNT;const t=B(this.resolvedSdkConfig);return t!==void 0?t-1:(this._configuration.ml?.analyzers.selfieConfig?.numSamples??K.Balanced.numSamples)-1}static _decodeToken(e){if(e.config?.allowOfflineMode)return;const t=e.network?.config?.token;if(!(!t||t.length===0))return N(t)}_notify(){for(const e of this._listeners)try{e()}catch{}}}
|
|
1
|
+
"use strict";import{File as p}from"expo-file-system";import{deleteImportedDocument as c}from"../../camera/imported_document_folder";import{JobType as m}from"../../core/models/job_type";import{CaptureType as u}from"../../core/models/ml_config";import{defaultFrameAspectRatio as l}from"../../core/models/document_type";import{UseSmileIDMetadataFactory as _}from"../../metadata/use_smile_id_metadata_factory";import{decodeSmileIDToken as g}from"../../data/util/use_smile_id_token_decoder";import{isTokenConsentComplete as k}from"../../data/model/token_payload";import{getNextScreen as S,supportingDocumentSide as b,documentPreviewFollowsCapture as C}from"./flow_navigation_manager_routing";import{currentDocumentCaptureSide as v,currentDocumentPreviewBorderFraction as y,currentDocumentPreviewPath as P,currentPreviewIsDocument as w,documentBorderFraction as D,documentCapturesBack as T,recordDocumentImageOrigin as I,retakeCurrentDocumentSide as F,setCapturedBackDocument as j,setCapturedFrontDocument as x,setCapturedVisaDocument as B,skipDocumentBack as E}from"./flow_navigation_manager_documents";import{logAnalyticsEvent as A,logKind as n,recordDocumentCaptureTelemetry as N,recordSelfieCaptureTelemetry as M,screenAnalyticsName as h}from"./flow_navigation_manager_analytics";import{beginSubmissionIfNeeded as O,retrySubmission as R,submit as J}from"./flow_navigation_manager_submission";import{markCapturedTake as G}from"../components/helpers/captured_image_uri";function f(s){return[s.frontDocumentPath,s.backDocumentPath,s.visaDocumentPath].filter(e=>e!==void 0)}export class FlowNavigationManager{_navigationPath=[];_captured={livenessPaths:[]};_documentBackSkipped=!1;_documentBorderFractions=new Map;_documentImageOrigins=new Map;_selfieCaptureTelemetry;_documentCaptureTelemetry=new Map;_cameraName;_devicePositions=[];_deviceMovementDetected=null;_jobSubmissionState={kind:"notAttempted"};_listeners=new Set;_steps;_configuration;_repository;_metadataProvider;_onExit;_disposed=!1;_submissionResponse;_capturedJob;_flowEnded=!1;resolvedSdkConfig;_resolvedPartnerId;_resolvedTokenPayload;get partnerId(){const e=this._resolvedPartnerId;return e&&e.length>0?e:this._configuration.network?.config?.partnerConfig?.partnerId??""}_sessionId;_submissionAttemptCount=0;constructor(e){this._configuration=e.configuration,this._onExit=e.onExit,this._repository=e.repository,this._metadataProvider=e.metadataProvider??new _,this._sessionId=this._metadataProvider.sessionId;const t=FlowNavigationManager._decodeToken(e.configuration);this.resolvedSdkConfig=t?.sdkConfig,this._resolvedPartnerId=t?.partnerId,this._resolvedTokenPayload=t?.tokenPayload;const i=e.configuration.screens.steps;this._steps=k(t?.tokenPayload?.consent)?i.filter(o=>o.kind!=="consent"):i;const r=this._steps[0];r&&(this._navigationPath=[r]),n(this,{kind:"flowStarted",jobType:this._jobType()}),r&&n(this,{kind:"screenViewed",screen:h(this,r)})}get configuration(){return this._configuration}get enhancedLivenessEnabled(){return this._steps.some(e=>e.kind==="capture"&&e.config.selfieConfig?.enableEnhancedLiveness===!0)}get documentType(){for(const e of this._steps)if(e.kind==="capture"&&e.config.captureType===u.document)return e.config.documentConfig?.documentType}get instructionsDocumentType(){const e=this.currentScreen,t=e?this._steps.indexOf(e)+1:0,i=this._steps.slice(t).find(r=>r.kind==="capture");return i?.kind==="capture"&&i.config.captureType===u.document?i.config.documentConfig?.documentType:void 0}get documentFrameAspectRatio(){for(const e of this._steps)if(e.kind==="capture"&&e.config.captureType===u.document){const t=e.config.documentConfig;return t?.resolvedAspectRatio??l(t?.documentType?.orientation??"Landscape")}}get navigationPath(){return this._navigationPath}get currentScreen(){return this._navigationPath[this._navigationPath.length-1]}get currentDepth(){return this._navigationPath.length-1}get isFirstScreen(){return this._navigationPath.length<=1}get isLastScreen(){return this.getNextScreen()===void 0}getNextScreen(){return S(this)}navigateToNext(){if(this._disposed)return;const e=this.getNextScreen();if(!e){const t=this._jobSubmissionState;if(this._submissionResponse){this._finishFlow({kind:"completed",job:this._submissionResponse});return}if(t.kind==="failure"){this._finishFlow({kind:"failed",error:t.error});return}const i=t.kind==="success"?t.response:{userId:"",jobId:"",status:"",message:""};this._finishFlow({kind:"completed",job:i});return}this._navigationPath=[...this._navigationPath,e],n(this,{kind:"screenViewed",screen:h(this,e)}),e.kind==="processing"&&this._jobSubmissionState.kind==="notAttempted"&&this._repository!==void 0&&(this._jobSubmissionState={kind:"loading"}),this._notify(),e.kind==="processing"&&this._jobSubmissionState.kind==="loading"&&this._repository!==void 0&&setTimeout(()=>{this._disposed||J(this)},0)}navigateBack(){if(!this._disposed&&this._capturedJob===void 0&&!(this._configuration.config?.skipApiSubmission&&this._jobSubmissionState.kind==="loading")){if(this.isFirstScreen){this._finishFlow({kind:"cancelled"});return}n(this,{kind:"retakeRequested"}),this._navigationPath=this._navigationPath.slice(0,-1),this._notify()}}navigateToStart(){if(this._disposed)return;const e=this._steps[0];this._navigationPath=e?[e]:[],this._notify()}exit(e={kind:"cancelled"}){this._disposed||e.kind!=="captured"&&this._finishFlow(e)}get captured(){return this._captured}get capturedJob(){return this._capturedJob}setCapturedSelfie(e,t){this._disposed||(G(e),this._captured={...this._captured,selfiePath:e,livenessPaths:Object.freeze([...t])},n(this,{kind:"selfieCaptured",livenessImageCount:t.length}),this._notify())}get selfieCaptureGeometry(){return this._selfieCaptureGeometry}_selfieCaptureGeometry;recordSelfieCaptureGeometry(e){e&&(this._selfieCaptureGeometry=e)}setCapturedFrontDocument(e,t=0){x(this,e,t)}setCapturedBackDocument(e,t=0){j(this,e,t)}supportingDocumentSide(){return b(this)}documentCapturesBack(){return T(this)}currentDocumentCaptureSide(){return v(this)}setCapturedVisaDocument(e,t=0){B(this,e,t)}documentPreviewFollowsCapture(){return C(this)}currentPreviewIsDocument(){return w(this)}currentDocumentPreviewPath(){return P(this)}documentBorderFraction(e){return D(this,e)}currentDocumentPreviewBorderFraction(){return y(this)}retakeCurrentDocumentSide(){F(this)}skipDocumentBack(){E(this)}recordDocumentImageOrigin(e,t){I(this,e,t)}recordSelfieCaptureTelemetry(e){M(this,e)}recordDocumentCaptureTelemetry(e,t){N(this,e,t)}setConsent(e){this._disposed||(this._captured={...this._captured,consentInformation:e},n(this,{kind:"consentCaptured"}),this._notify())}get jobSubmissionState(){return this._jobSubmissionState}beginSubmissionIfNeeded(){O(this)}retrySubmission(){R(this)}_setCaptured(e){const t=new Set(f(e));for(const i of f(this._captured))t.has(i)||c(i);this._captured=e}_deleteCapturedFiles(){if(this._configuration.config?.allowOfflineMode)return;const{selfiePath:e,livenessPaths:t,frontDocumentPath:i,backDocumentPath:r,visaDocumentPath:o}=this._captured;for(const d of[e,...t,i,r,o])if(d){try{const a=new p(d);a.exists&&a.delete()}catch{}c(d)}}_finishFlow(e){this._capturedJob!==void 0&&e.kind!=="captured"||(this._flowEnded=!0,e.kind!=="captured"&&this._deleteCapturedFiles(),e.kind==="completed"?n(this,e.job.jobId?{kind:"flowCompletedSuccess",jobId:e.job.jobId}:{kind:"flowCompletedSuccess"}):e.kind==="failed"&&n(this,{kind:"flowCompletedFailure",errorMessage:e.error instanceof Error?e.error.message:String(e.error)}),e.kind==="captured"&&n(this,{kind:"flowCompletedCaptured"}),this._onExit(e))}logAnalyticsEvent(e){A(this,e)}_jobType(){return this._configuration.network?.config?.jobType??m.unknown}subscribe(e){return this._listeners.add(e),()=>{this._listeners.delete(e)}}dispose(){this._disposed=!0,this._listeners.clear()}static _decodeToken(e){if(e.config?.allowOfflineMode)return;const t=e.network?.config?.token;if(!(!t||t.length===0))return g(t)}_notify(){for(const e of this._listeners)try{e()}catch{}}}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import type { ScreenSpec } from "./dsl/builder/screens_builder";
|
|
2
|
+
import { type UseSmileIDAnalyticsEventKind, type UseSmileIDAnalyticsScreenName } from "./analytics/use_smile_id_analytics_event_kind";
|
|
3
|
+
import type { MetadataEntry } from "../../metadata/use_smile_id_metadata";
|
|
4
|
+
import type { CaptureTelemetry } from "../screen/use_smile_id_capture_screen";
|
|
5
|
+
import { DocumentSide } from "@smileid/usesmileid_bridge";
|
|
6
|
+
import type { FlowNavigationManager } from "./flow_navigation_manager";
|
|
7
|
+
/**
|
|
8
|
+
* Analytics events and the capture telemetry the submission metadata carries. Functions take the `FlowNavigationManager` first; its public methods delegate here.
|
|
9
|
+
*/
|
|
10
|
+
export declare function recordSelfieCaptureTelemetry(manager: FlowNavigationManager, telemetry: CaptureTelemetry): void;
|
|
11
|
+
export declare function recordDocumentCaptureTelemetry(manager: FlowNavigationManager, side: DocumentSide, telemetry: CaptureTelemetry): void;
|
|
12
|
+
/** Per-image document origin wire entries (front, back, visa; omitted when unset). */
|
|
13
|
+
export declare function documentImageOriginEntries(manager: FlowNavigationManager): MetadataEntry[];
|
|
14
|
+
/**
|
|
15
|
+
* Capture telemetry + image-property wire entries. Durations and retries keep
|
|
16
|
+
* a meaningful 0 (capture ran) and are omitted only when that capture type
|
|
17
|
+
* never ran. Color depth / pixel config are emitted for each present capture;
|
|
18
|
+
* document sizes when measured.
|
|
19
|
+
*/
|
|
20
|
+
export declare function captureTelemetryEntries(manager: FlowNavigationManager): MetadataEntry[];
|
|
21
|
+
export declare function logAnalyticsEvent(manager: FlowNavigationManager, event: UseSmileIDAnalyticsEventKind): void;
|
|
22
|
+
export declare function logKind(manager: FlowNavigationManager, event: UseSmileIDAnalyticsEventKind): void;
|
|
23
|
+
export declare function screenAnalyticsName(manager: FlowNavigationManager, screen: ScreenSpec): UseSmileIDAnalyticsScreenName;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{UseSmileIDAnalyticsParamKeys as d,UseSmileIDAnalyticsScreenNames as r}from"./analytics/use_smile_id_analytics_event";import{encodeAnalyticsEventKind as p}from"./analytics/use_smile_id_analytics_event_kind";import{DOCUMENT_BACK_IMAGE_ORIGIN_KEY as l,DOCUMENT_FRONT_IMAGE_ORIGIN_KEY as v,DOCUMENT_VISA_IMAGE_ORIGIN_KEY as E}from"../../metadata/document_image_origin";import{CAPTURE_IMAGE_COLOR_DEPTH as a,CAPTURE_IMAGE_PIXEL_CONFIG as f}from"../../metadata/captured_image_properties";import{DocumentSide as o}from"@smileid/usesmileid_bridge";export function recordSelfieCaptureTelemetry(e,t){e._disposed||(e._selfieCaptureTelemetry=t,m(e,t))}export function recordDocumentCaptureTelemetry(e,t,i){e._disposed||(e._documentCaptureTelemetry.set(t,i),m(e,i))}function m(e,t){t.cameraName&&(e._cameraName=t.cameraName),t.devicePositions.length>0&&(e._devicePositions=t.devicePositions,e._deviceMovementDetected=t.deviceMovementDetected)}export function documentImageOriginEntries(e){const t=[],i=e._documentImageOrigins.get(o.Front);i!==void 0&&t.push({name:v,value:i});const n=e._documentImageOrigins.get(o.Back);n!==void 0&&t.push({name:l,value:n});const _=e._documentImageOrigins.get(o.Visa);return _!==void 0&&t.push({name:E,value:_}),t}export function captureTelemetryEntries(e){const t=[],i=(s,c)=>t.push({name:s,value:c}),n=e._selfieCaptureTelemetry;n&&(i("selfie_capture_duration_ms",String(n.durationMs)),i("selfie_capture_retries",String(n.retries))),e._captured.selfiePath!==void 0&&(i("selfie_image_color_depth",String(a)),i("selfie_image_pixel_config",f)),e._cameraName&&i("camera_name",e._cameraName),e._devicePositions.length>0&&(i("device_positions",JSON.stringify(e._devicePositions)),e._deviceMovementDetected!==null&&i("device_movement_detected",String(e._deviceMovementDetected)));const _=s=>{switch(s){case o.Back:return"back";case o.Visa:return"visa";default:return"front"}};for(const s of[o.Front,o.Back,o.Visa]){const c=_(s),u=e._documentCaptureTelemetry.get(s);u&&(i(`document_${c}_capture_duration_ms`,String(u.durationMs)),i(`document_${c}_capture_retries`,String(u.retries)),i(`document_${c}_image_color_depth`,String(a)),i(`document_${c}_image_pixel_config`,f))}return t}export function logAnalyticsEvent(e,t){e._disposed||logKind(e,t)}export function logKind(e,t){const{type:i,extras:n}=p(t);I(e,i,n)}function I(e,t,i={}){const n=e._configuration.onAnalyticsEvent;n&&n({type:t,extras:{...i,[d.sessionId]:e._sessionId,[d.timestamp]:String(Date.now())}})}export function screenAnalyticsName(e,t){return{consent:r.consent,instructions:r.instructions,capture:r.capture,preview:r.preview,processing:r.processing}[t.kind]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { DocumentImageOrigin } from "../../metadata/document_image_origin";
|
|
2
|
+
import { DocumentSide } from "@smileid/usesmileid_bridge";
|
|
3
|
+
import type { FlowNavigationManager } from "./flow_navigation_manager";
|
|
4
|
+
/**
|
|
5
|
+
* Document sides: what is captured, previewed, retaken or skipped. Functions take the `FlowNavigationManager` first; its public methods delegate here.
|
|
6
|
+
*/
|
|
7
|
+
export declare function setCapturedFrontDocument(manager: FlowNavigationManager, path: string, borderFraction?: number): void;
|
|
8
|
+
export declare function setCapturedBackDocument(manager: FlowNavigationManager, path: string, borderFraction?: number): void;
|
|
9
|
+
export declare function documentCapturesBack(manager: FlowNavigationManager): boolean;
|
|
10
|
+
export declare function currentDocumentCaptureSide(manager: FlowNavigationManager): DocumentSide;
|
|
11
|
+
export declare function setCapturedVisaDocument(manager: FlowNavigationManager, path: string, borderFraction?: number): void;
|
|
12
|
+
export declare function currentPreviewIsDocument(manager: FlowNavigationManager): boolean;
|
|
13
|
+
export declare function currentDocumentPreviewPath(manager: FlowNavigationManager): string | undefined;
|
|
14
|
+
export declare function documentBorderFraction(manager: FlowNavigationManager, side: DocumentSide): number;
|
|
15
|
+
export declare function currentDocumentPreviewBorderFraction(manager: FlowNavigationManager): number;
|
|
16
|
+
export declare function retakeCurrentDocumentSide(manager: FlowNavigationManager): void;
|
|
17
|
+
export declare function skipDocumentBack(manager: FlowNavigationManager): void;
|
|
18
|
+
export declare function recordDocumentImageOrigin(manager: FlowNavigationManager, side: DocumentSide, origin: DocumentImageOrigin): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{DocumentSide as u}from"@smileid/usesmileid_bridge";import{logKind as c}from"./flow_navigation_manager_analytics";import{capturedSupportingDocument as d,precedingStepIsDocumentCapture as s}from"./flow_navigation_manager_routing";import{markCapturedTake as r}from"../components/helpers/captured_image_uri";export function setCapturedFrontDocument(t,e,o=0){if(t._disposed)return;const n={...t._captured,frontDocumentPath:e};t._documentBackSkipped=!1,delete n.backDocumentPath,delete n.visaDocumentPath;for(const i of[u.Back,u.Visa])t._documentImageOrigins.delete(i),t._documentCaptureTelemetry.delete(i),t._documentBorderFractions.delete(i);p(t,u.Front,o),r(e),t._setCaptured(n),c(t,{kind:"documentCaptured",side:u.Front}),t._notify()}export function setCapturedBackDocument(t,e,o=0){t._disposed||(t._documentBackSkipped=!1,r(e),t._setCaptured({...t._captured,backDocumentPath:e}),p(t,u.Back,o),c(t,{kind:"documentCaptured",side:u.Back}),t._notify())}export function documentCapturesBack(t){return t.supportingDocumentSide()===u.Back}export function currentDocumentCaptureSide(t){return t._captured.frontDocumentPath===void 0?u.Front:t.supportingDocumentSide()??u.Back}export function setCapturedVisaDocument(t,e,o=0){t._disposed||(r(e),t._setCaptured({...t._captured,visaDocumentPath:e}),p(t,u.Visa,o),c(t,{kind:"documentCaptured",side:u.Visa}),t._notify())}export function currentPreviewIsDocument(t){const e=t.currentScreen;return!e||e.kind!=="preview"?!1:s(t,t._steps.indexOf(e))}export function currentDocumentPreviewPath(t){return d(t)??t._captured.frontDocumentPath}export function documentBorderFraction(t,e){return t._documentBorderFractions.get(e)??0}export function currentDocumentPreviewBorderFraction(t){const e=t.supportingDocumentSide();return e!==void 0&&d(t)!==void 0?t.documentBorderFraction(e):t.documentBorderFraction(u.Front)}function p(t,e,o){Number.isFinite(o)&&o>0?t._documentBorderFractions.set(e,o):t._documentBorderFractions.delete(e)}export function retakeCurrentDocumentSide(t){if(t._disposed)return;const e={...t._captured},o=t.supportingDocumentSide();o!==void 0&&d(t)!==void 0?(o===u.Visa?delete e.visaDocumentPath:delete e.backDocumentPath,t._documentImageOrigins.delete(o),t._documentCaptureTelemetry.delete(o),t._documentBorderFractions.delete(o)):(delete e.frontDocumentPath,t._documentImageOrigins.delete(u.Front),t._documentBorderFractions.delete(u.Front),t._documentBackSkipped=!1),t._setCaptured(e),t._notify()}export function skipDocumentBack(t){t._disposed||t.supportingDocumentSide()!==u.Visa&&(t._documentBackSkipped=!0,t._notify())}export function recordDocumentImageOrigin(t,e,o){t._disposed||t._documentImageOrigins.set(e,o)}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import type { JobRequest } from "../../data/model/job_request";
|
|
2
|
+
import type { FlowNavigationManager } from "./flow_navigation_manager";
|
|
3
|
+
/**
|
|
4
|
+
* Build a typed `JobRequest` from `jobType` + captured artifacts.
|
|
5
|
+
* Throws a descriptive message when a required capture is missing.
|
|
6
|
+
*/
|
|
7
|
+
export declare function assembleJob(manager: FlowNavigationManager): JobRequest;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{JobType as c}from"../../core/models/job_type";import{MissingJobTypeException as b,MissingRequiredFieldException as r}from"../../core/exception/job_validation_exceptions";import{InvalidFieldValueException as w}from"../../core/exception/invalid_field_value_exception";import{configurationMetadataEntries as E}from"../../metadata/metadata_configuration_mappers";import{numSamplesOverride as C}from"../../data/model/sdk_config";import{bindsUserDetails as N,isIdFieldBoundByToken as k,isTokenConsentComplete as V}from"../../data/model/token_payload";import{isUserDetailsPayloadEmpty as S,userDetailsPayloadFrom as _}from"../../data/model/user_details_payload";import{EnhancedSmartSelfieConfig as L,FaceCaptureDefaults as x}from"@smileid/usesmileid_bridge";import{captureTelemetryEntries as j,documentImageOriginEntries as F}from"./flow_navigation_manager_analytics";const K=Object.freeze({granted:!1,grantedAt:"",noticeLanguage:"",noticePrivacyPolicyUrl:""});export function assembleJob(e){const n=e._configuration,s=n.network?.config?.jobType??c.unknown,d=V(e._resolvedTokenPayload?.consent)?void 0:e._captured.consentInformation??n.consentInformation??K,f=d!==void 0?{consent:d}:{},D=e._metadataProvider.make(e.resolvedSdkConfig),I=[...F(e),...j(e),...E(n)],l=D.withAdditionalEntries(I);switch(s){case c.smartSelfieEnrollment:{const t=p(e),i=m(e,n);return{jobType:c.smartSelfieEnrollment,selfieImage:t.selfiePath,livenessImages:t.livenessPaths,...i!==void 0?{userDetails:i}:{},...f,metadata:l,enhanced:!1,expectedLivenessImageCount:y(e)}}case c.smartSelfieAuthentication:{const t=p(e),i=m(e,n),o=U(e,n);return{jobType:c.smartSelfieAuthentication,selfieImage:t.selfiePath,livenessImages:t.livenessPaths,...i!==void 0?{userDetails:i}:{},userId:o,...f,metadata:l,enhanced:!1,expectedLivenessImageCount:y(e)}}case c.biometricKyc:{const t=p(e),i=n.biometricKYCParams;if(!i)throw new r({fieldName:"biometricKYCParams"});const o=m(e,n);return{jobType:c.biometricKyc,selfieImage:t.selfiePath,livenessImages:t.livenessPaths,params:{...i,...v(e,i)},...o!==void 0?{userDetails:o}:{},...f,metadata:l,expectedLivenessImageCount:y(e)}}case c.documentVerification:{const t=p(e),i=h(e),o=n.documentVerificationParams;if(!o)throw new r({fieldName:"documentVerificationParams"});const a=m(e,n);return{jobType:c.documentVerification,...P(e,t,i),country:u(e,o.country,"country"),...o.idType?{idType:u(e,o.idType,"idType")}:{},...a!==void 0?{userDetails:a}:{},...f,metadata:l,expectedLivenessImageCount:y(e)}}case c.enhancedDocumentVerification:{const t=p(e),i=h(e),o=n.enhancedDocumentVerificationParams;if(!o)throw new r({fieldName:"enhancedDocumentVerificationParams"});const a=m(e,n);return{jobType:c.enhancedDocumentVerification,...P(e,t,i),country:u(e,o.country,"country"),idType:u(e,o.idType,"idType"),...a!==void 0?{userDetails:a}:{},...f,metadata:l,expectedLivenessImageCount:y(e)}}case c.residencyDocumentVerification:{const t=p(e),i=h(e),o=n.residencyDocumentVerificationParams;if(!o)throw new r({fieldName:"residencyDocumentVerificationParams"});const a=A(e);if(!a)throw new r({fieldName:"visaDocument"});const T=m(e,n);return{jobType:c.residencyDocumentVerification,selfieImage:t.selfiePath,livenessImages:t.livenessPaths,frontDocument:i,visaDocument:a,country:u(e,o.country,"country"),idType:u(e,o.idType,"idType"),...T!==void 0?{userDetails:T}:{},...f,metadata:l,expectedLivenessImageCount:y(e)}}case c.enhancedKyc:{const t=n.enhancedKYCParams;if(!t)throw new r({fieldName:"enhancedKYCParams"});const i=m(e,n);return{jobType:c.enhancedKyc,params:{...t,...v(e,t)},...i!==void 0?{userDetails:i}:{},...f,metadata:l}}case c.bvn:throw new w({fieldName:"jobType",reason:"BVN submission is not yet supported"});case c.unknown:default:throw new b}}function p(e){const{selfiePath:n,livenessPaths:s}=e._captured;if(!n)throw new r({fieldName:"selfieImage"});return{selfiePath:n,livenessPaths:s}}function u(e,n,s){if(k(e._resolvedTokenPayload,s))return"";if(!n.trim())throw new r({fieldName:s});return n}function v(e,n){return{idType:u(e,n.idType,"idType"),idNumber:u(e,n.idNumber,"idNumber"),country:u(e,n.country,"country")}}function m(e,n){const s=e._resolvedTokenPayload,d=n.userDetails?_(n.userDetails,s):void 0;return d&&!S(d)?d:N(s)?void 0:{}}function U(e,n){const s=n.userId?.trim();if(!s)throw new r({fieldName:"userId"});return s}function h(e){const{frontDocumentPath:n}=e._captured;if(!n)throw new r({fieldName:"frontDocument"});return n}function P(e,n,s){const{backDocumentPath:d}=e._captured;return{selfieImage:n.selfiePath,livenessImages:n.livenessPaths,frontDocument:s,...d?{backDocument:d}:{}}}function A(e){return e._captured.visaDocumentPath}function y(e){if(e.enhancedLivenessEnabled)return L.EXPECTED_LIVENESS_IMAGE_COUNT;const s=C(e.resolvedSdkConfig);return s!==void 0?s-1:x.numSamples-1}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { ScreenSpec } from "./dsl/builder/screens_builder";
|
|
2
|
+
import { DocumentSide } from "@smileid/usesmileid_bridge";
|
|
3
|
+
import type { FlowNavigationManager } from "./flow_navigation_manager";
|
|
4
|
+
/**
|
|
5
|
+
* Where the flow goes next, including the per-side document loop. Functions take the `FlowNavigationManager` first; its public methods delegate here.
|
|
6
|
+
*/
|
|
7
|
+
export declare function getNextScreen(manager: FlowNavigationManager): ScreenSpec | undefined;
|
|
8
|
+
export declare function supportingDocumentSide(manager: FlowNavigationManager): DocumentSide | undefined;
|
|
9
|
+
/** Captured path for {@link supportingDocumentSide}, or undefined when absent or not yet captured. */
|
|
10
|
+
export declare function capturedSupportingDocument(manager: FlowNavigationManager): string | undefined;
|
|
11
|
+
export declare function documentPreviewFollowsCapture(manager: FlowNavigationManager): boolean;
|
|
12
|
+
export declare function precedingStepIsDocumentCapture(manager: FlowNavigationManager, index: number): boolean;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{JobType as o}from"../../core/models/job_type";import{CaptureType as u}from"../../core/models/ml_config";import{DocumentSide as i}from"@smileid/usesmileid_bridge";export function getNextScreen(e){const t=e.currentScreen;if(!t)return;const n=e._steps.indexOf(t);if(!(n<0)){if(t.kind==="preview"&&precedingStepIsDocumentCapture(e,n)&&e.supportingDocumentSide()!==void 0&&capturedSupportingDocument(e)===void 0&&!e._documentBackSkipped){const c=e._steps[n-1];if(c!==void 0)return c}return t.kind==="capture"&&t.config.captureType===u.document&&e._documentBackSkipped&&e._steps[n+1]?.kind==="preview"?e._steps[n+2]:t.kind==="capture"&&t.config.captureType===u.document&&e.supportingDocumentSide()!==void 0&&e._captured.frontDocumentPath!==void 0&&capturedSupportingDocument(e)===void 0&&!e._documentBackSkipped&&!e.documentPreviewFollowsCapture()?t:e._steps[n+1]}}export function supportingDocumentSide(e){if(e._configuration.network?.config?.jobType===o.residencyDocumentVerification)return i.Visa;for(const t of e._steps)if(t.kind==="capture"&&t.config.captureType===u.document){const n=t.config.documentConfig;return n?.documentType?.hasBackSide===!0&&(n?.captureBothSides??!1)?i.Back:void 0}}export function capturedSupportingDocument(e){switch(e.supportingDocumentSide()){case i.Visa:return e._captured.visaDocumentPath;case i.Back:return e._captured.backDocumentPath;default:return}}export function documentPreviewFollowsCapture(e){const t=e._steps.findIndex(n=>n.kind==="capture"&&n.config.captureType===u.document);return t<0?!1:e._steps[t+1]?.kind==="preview"}export function precedingStepIsDocumentCapture(e,t){const n=e._steps[t-1];return n?.kind==="capture"&&n.config.captureType===u.document}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import type { FlowNavigationManager } from "./flow_navigation_manager";
|
|
2
|
+
/**
|
|
3
|
+
* Submission and the skip-submission hand-over. Functions take the `FlowNavigationManager` first; its public methods delegate here.
|
|
4
|
+
*/
|
|
5
|
+
export declare function beginSubmissionIfNeeded(manager: FlowNavigationManager): void;
|
|
6
|
+
export declare function retrySubmission(manager: FlowNavigationManager): void;
|
|
7
|
+
/**
|
|
8
|
+
* Build the request, dispatch via repository, update state. Errors
|
|
9
|
+
* from `assembleJob(manager)` (missing captures / bad job type) map to the
|
|
10
|
+
* `failure` state rather than propagating as unhandled rejections.
|
|
11
|
+
*
|
|
12
|
+
* Callers hold the one-submission-at-a-time guard: `beginSubmissionIfNeeded()`
|
|
13
|
+
* calls this only from `notAttempted`, and `navigateToNext()` sets `loading`
|
|
14
|
+
* first. It sets `loading` itself before its first `await`, so a second call
|
|
15
|
+
* that checks the state finds one already running.
|
|
16
|
+
*/
|
|
17
|
+
export declare function submit(manager: FlowNavigationManager): Promise<void>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"use strict";import{capturedJobFrom as u}from"../../data/model/captured_job";import{logKind as d}from"./flow_navigation_manager_analytics";import{assembleJob as p}from"./flow_navigation_manager_job_request";export function beginSubmissionIfNeeded(i){i._disposed||i._jobSubmissionState.kind==="notAttempted"&&submit(i)}export function retrySubmission(i){if(i._disposed)return;const{kind:o}=i._jobSubmissionState;o==="loading"||o==="skipped"||(t(i,{kind:"notAttempted"}),i.beginSubmissionIfNeeded())}function t(i,o){i._disposed||(i._jobSubmissionState=o,i._notify())}export async function submit(i){if(!i._repository){t(i,{kind:"failure",error:new Error("Job submission not configured \u2014 no network/repository was supplied to <UseSmileIDBuilder>. Call `b.network((n) => n.config((c) => { c.token = ...; c.partnerConfig((p) => { p.partnerId = ...; }); }))`.")});return}let o;try{o=p(i)}catch(s){t(i,{kind:"failure",error:s instanceof Error?s:new Error(String(s))});return}if(i._configuration.config?.skipApiSubmission){await f(i,o,i._repository);return}t(i,{kind:"loading"}),i._submissionAttemptCount+=1,d(i,{kind:"jobSubmitted",jobType:i._jobType(),attempt:i._submissionAttemptCount});const e=await i._repository.submit(o,i.resolvedSdkConfig);if(!i._disposed){if(e.status==="success")i._submissionResponse=e.value,t(i,{kind:"success",response:e.value});else if(e.status==="failure"){const s=e.error instanceof Error?e.error:new Error(String(e.error));t(i,{kind:"failure",error:s})}}}async function f(i,o,e){if(i._flowEnded){t(i,{kind:"notAttempted"});return}t(i,{kind:"loading"});const s=await e.seal(o,i.resolvedSdkConfig);if(i._disposed)return;if(s.status!=="success"){const r=s.status==="failure"?s.error:void 0;t(i,{kind:"failure",error:r instanceof Error?r:new Error(String(r??"Sealing returned an unexpected result"))});return}if(i._flowEnded){t(i,{kind:"notAttempted"});return}d(i,{kind:"jobCaptured",jobType:i._jobType()});const n=u(o,i._sessionId,s.value);i._capturedJob=n,t(i,{kind:"skipped"}),i._finishFlow({kind:"captured",job:n})}
|
|
@@ -13,7 +13,7 @@ import type { SdkConfig } from "../../../../data/model/sdk_config";
|
|
|
13
13
|
* - Liveness JPEG quality (`livenessJpegQuality`): integer `1..100`.
|
|
14
14
|
* - `numSamples` from `livenessImageCount + 1`: suppressed when ESS is
|
|
15
15
|
* active (head-turn manages its own count). Falls back to the base
|
|
16
|
-
* config's `numSamples` (
|
|
16
|
+
* config's `numSamples` (`FaceCaptureDefaults.numSamples`) when the
|
|
17
17
|
* claim is absent or invalid.
|
|
18
18
|
*
|
|
19
19
|
* `faceConfigSchema` re-applies the ESS frame-count pin at every
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{UseSmileIDErrorCode as i,UseSmileIDException as
|
|
1
|
+
"use strict";import{NetworkServerException as s,UseSmileIDErrorCode as i,UseSmileIDException as n,isNetworkErrorCode as t,isRetryableErrorCode as E}from"../../../../core/exception";export function resolveFailureMessage(o,r){if(!(o instanceof n))return r.siProcessingErrorGeneric;const e=o.errorCode;return e===i.Camera.PermissionDenied?r.siProcessingErrorCameraPermission:t(e)?e===i.Network.RequestFailed?o instanceof s?r.siProcessingErrorGeneric:r.siProcessingErrorNoConnection:e===i.Network.RateLimit||e===i.Network.ServerError?r.siProcessingErrorRetryLater:E(e)?r.siProcessingErrorNoConnection:r.siProcessingErrorUnavailable:r.siProcessingErrorGeneric}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{jsx as
|
|
1
|
+
"use strict";import{jsx as D}from"react/jsx-runtime";import{useEffect as j,useState as g}from"react";import{StyleSheet as J,View as Q}from"react-native";import{CaptureReadyEventKind as I,DeviceIntegrityProvider as W,DocumentSide as l,ImageType as A}from"@smileid/usesmileid_bridge";import{CameraLens as $}from"../../../camera/camera_lens";import{KameraConfigFactory as q}from"../../../camera/kamera_config_factory";import{CaptureType as s}from"../../../core/models/ml_config";import{defaultFrameAspectRatio as X,documentFrameOrientation as Y}from"../../../core/models/document_type";import{SmileExifTagger as B}from"@smileid/usesmileid_bridge/exif/smile_exif_tagger";import{resolveDeviceModel as Z}from"../../../metadata/use_smile_id_metadata_factory";import{claimAnalyzer as P,releaseAnalyzer as N}from"./helpers/analyzer_lifecycle";import{resolveFaceSessionConfig as M}from"./helpers/face_session_config";import{useCaptureOrientationLock as ee}from"../../screen/helpers/use_capture_orientation_lock";import{localizedDocumentName as te}from"../../screen/helpers/instructions_screen_helpers";import{resolveJpegQuality as oe}from"../../../data/model/sdk_config_capture";import{AttributionResolver as re,flowShowAttribution as T}from"../config/attribution_resolver";import{UseSmileIDCaptureScreen as ne}from"../../screen/use_smile_id_capture_screen";import{cameraExceptionFromKameraError as ie}from"../../../camera/kamera_error_mapping";import{defaultLightTheme as se}from"../../theme/theme";import{UseSmileIDDocumentBackInstructions as ce}from"../../screen/use_smile_id_document_back_instructions";import{UseSmileIDInstructionsScreen as ue}from"../../screen/use_smile_id_instructions_screen";import{DOCUMENT_HERO_VISA_ANIMATION as le,documentGuidelines as me}from"../model/instructions_defaults";import{useUseSmileIDLocalizations as de}from"../../../l10n/use_smile_id_localizations_provider";import{useFlowNavigation as ae}from"../flow_navigation_context";import{UseSmileIDOrchestratedScreenHost as fe}from"./use_smile_id_orchestrated_screen_host";export function OrchestratedCaptureScreen({configuration:n}){const i=ae(),C=de(),t=n.captureType,d=n.documentConfig,a=d?.documentType,k=i.supportingDocumentSide(),S=k!==void 0,v=d?.allowSkipBack??!1,E=i.documentPreviewFollowsCapture(),O=i.captured.frontDocumentPath!==void 0,[r,b]=g(S&&O&&k!==void 0?k:l.Front),[z,h]=g(S&&O),L=i.configuration.config?.exitOrientations,x=t===s.document&&!z?Y(a,d?.resolvedAspectRatio):"Portrait",V=ee(x,{...L!==void 0?{exitLock:L}:{}}),c=t===s.selfie?i.configuration.ml?.analyzers.selfie:i.configuration.ml?.analyzers.document;return j(()=>{if(!c)return;let e=0;if(t===s.selfie&&c.kind==="face"){const f=i.configuration.ml?.analyzers.selfieConfig??{analyzerFactoryKey:c.key};e=P(()=>c.configure(M(f,n.selfieConfig?.enableEnhancedLiveness??!1,i.resolvedSdkConfig)))}else if(t===s.document&&c.kind==="document"){const f=oe(i.resolvedSdkConfig?.document),u=q.create(s.document,$.back).analysis,w=n.documentConfig?.documentType?.kind,o=n.documentConfig?.resolvedAspectRatio,p=o!==void 0&&Number.isFinite(o)&&o>0?o:void 0;e=P(()=>c.configure({documentSide:r,...f!==void 0?{documentJpegQuality:f}:{},...w!==void 0?{documentKind:w}:{},...p!==void 0?{knownAspectRatio:p}:{},sessionFrameWidth:u.targetWidth,sessionFrameHeight:u.targetHeight}))}return()=>{N(e,c)}},[c,t,i,n,r]),D(fe,{content:({navigationManager:e,onBack:f,onNavigateNext:u})=>{if(!c)throw new Error(`OrchestratedCaptureScreen: no ${t} analyzer registered in the ML DSL`);if(t===s.document&&S&&z){const o=()=>{if(E){f();return}h(!1),b(l.Front)};return r===l.Visa?D(ue,{titlePrefix:C.siInstructionsTitlePrefix,titleEmphasis:C.siInstructionsEmphasisVisa,heroSource:le,guidelinesSectionTitle:C.siInstructionsCaptureGuidelines,guidelines:me(a),showAttribution:T(e.configuration),showHeroOval:!1,showHeroOvalProgress:!1,showCardBackground:!0,onContinue:()=>h(!1),onBack:o}):D(ce,{documentTypeDisplayName:a?te(a,C):"",allowSkip:v,showAttribution:T(e.configuration),onCaptureBack:()=>h(!1),onSkip:()=>{e.skipDocumentBack(),u()},onBack:o})}const w=e.configuration.theme?.light??se;return V?D(ne,{captureType:t,analyzer:c,onAnalyticsEvent:o=>e.logAnalyticsEvent(o),theme:w,enableEnhancedLiveness:n.selfieConfig?.enableEnhancedLiveness??!1,allowAgentMode:n.selfieConfig?.allowAgentMode??!1,showAttribution:re.resolveForCapture({captureType:t,showAttribution:T(e.configuration)}),...t===s.document&&d?{knownIdAspectRatio:d.resolvedAspectRatio??X(a?.orientation??"Landscape"),captureMode:d.captureMode,allowGalleryUpload:d.allowGalleryUpload,documentSide:r,...a?.kind?{documentTypeKind:a.kind}:{},onDocumentOrigin:o=>e.recordDocumentImageOrigin(r,o),onClose:()=>e.exit()}:{},...n.startButton!==void 0?{startButton:n.startButton}:{},onBack:()=>{if(t===s.document&&S&&r!==l.Front){h(!0);return}f()},onCameraError:(o,p)=>{e.exit({kind:"failed",error:ie(o,p)})},onCaptureComplete:(o,p,K,_)=>{const F=K??0,y=pe(o,t);if(!y)return;const H=e.partnerId,G=t===s.selfie?A.Selfie:r===l.Visa?A.DocumentVisa:r===l.Back?A.DocumentBack:A.DocumentFront,R=o.filter(m=>m.kind===I.Liveness).map(m=>m.url),U=Z();W.signals().then(({fingerprint:m})=>B.setContext({partnerId:H,...U?{deviceModel:U}:{},...m?{fingerprint:m}:{}})).then(async()=>{await B.finalize(y,G),await Promise.all(R.map(m=>B.finalize(m,A.Liveness)))}).catch(()=>{}).finally(async()=>{if(t===s.selfie){e.setCapturedSelfie(y,R),e.recordSelfieCaptureGeometry(_),e.recordSelfieCaptureTelemetry(p),u();return}if(e.recordDocumentCaptureTelemetry(r,p),S&&k!==void 0&&r===l.Front){e.setCapturedFrontDocument(y,F),E?u():(b(k),h(!0));return}if(r===l.Visa){e.setCapturedVisaDocument(y,F),u();return}if(S&&r===l.Back){e.setCapturedBackDocument(y,F),u();return}e.setCapturedFrontDocument(y,F),u()})}},t===s.document?`document-capture-${r}`:"capture"):D(Q,{style:[J.absoluteFill,{backgroundColor:w.colors.offBlack}],testID:"si_capture_orientation_pending"})}})}function pe(n,i){const C=i===s.selfie?I.Selfie:I.Document;return n.find(t=>t.kind===C)?.url}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{jsx as n}from"react/jsx-runtime";import{useCallback as a}from"react";import{flowShowAttribution as m}from"../config/attribution_resolver";import{UseSmileIDInstructionsScreen as d}from"../../screen/use_smile_id_instructions_screen";import{UseSmileIDOrchestratedScreenHost as f}from"./use_smile_id_orchestrated_screen_host";import{resolveInstructionsConfig as h}from"../../screen/helpers/instructions_screen_helpers";import{alwaysEnabledSlot as p}from"./helpers/always_enabled_slot";import{useUseSmileIDLocalizations as S}from"../../../l10n/use_smile_id_localizations_provider";import{getCameraPermissionStatus as w,requestCameraPermission as C}from"../../../camera/camera_permissions";export function OrchestratedInstructionsScreen({configuration:o}){const r=S();return n(f,{content:t=>n(P,{renderProps:t,configuration:o,localizations:r})})}function P({renderProps:{navigationManager:o,onBack:r,onNavigateNext:t},configuration:s,localizations:u}){const l=a(async()=>{if(await w()==="granted"){t();return}await C()==="granted"&&t()},[t]),i=o.
|
|
1
|
+
"use strict";import{jsx as n}from"react/jsx-runtime";import{useCallback as a}from"react";import{flowShowAttribution as m}from"../config/attribution_resolver";import{UseSmileIDInstructionsScreen as d}from"../../screen/use_smile_id_instructions_screen";import{UseSmileIDOrchestratedScreenHost as f}from"./use_smile_id_orchestrated_screen_host";import{resolveInstructionsConfig as h}from"../../screen/helpers/instructions_screen_helpers";import{alwaysEnabledSlot as p}from"./helpers/always_enabled_slot";import{useUseSmileIDLocalizations as S}from"../../../l10n/use_smile_id_localizations_provider";import{getCameraPermissionStatus as w,requestCameraPermission as C}from"../../../camera/camera_permissions";export function OrchestratedInstructionsScreen({configuration:o}){const r=S();return n(f,{content:t=>n(P,{renderProps:t,configuration:o,localizations:r})})}function P({renderProps:{navigationManager:o,onBack:r,onNavigateNext:t},configuration:s,localizations:u}){const l=a(async()=>{if(await w()==="granted"){t();return}await C()==="granted"&&t()},[t]),i=o.instructionsDocumentType,e=h(s,{enhancedLivenessEnabled:o.enhancedLivenessEnabled,...i?{documentType:i}:{}},u),c=p(s.continueButton);return n(d,{titlePrefix:e.titlePrefix,titleEmphasis:e.titleEmphasis,heroSource:e.heroSource,guidelinesSectionTitle:e.guidelinesSectionTitle,guidelines:e.guidelines,showAttribution:m(o.configuration),showHeroOval:e.showHeroOval,showHeroOvalProgress:e.showHeroOvalProgress,showCardBackground:e.showCardBackground,...c!==void 0?{continueButton:c}:{},onContinue:l,onBack:r})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";import{jsx as r}from"react/jsx-runtime";import{flowShowAttribution as s}from"../config/attribution_resolver";import{UseSmileIDPreviewScreen as
|
|
1
|
+
"use strict";import{jsx as r}from"react/jsx-runtime";import{flowShowAttribution as s}from"../config/attribution_resolver";import{UseSmileIDPreviewScreen as p}from"../../screen/use_smile_id_preview_screen";import{UseSmileIDDocumentPreviewScreen as l}from"../../screen/use_smile_id_document_preview_screen";import{UseSmileIDOrchestratedScreenHost as d}from"./use_smile_id_orchestrated_screen_host";import{defaultFrameAspectRatio as f}from"../../../core/models/document_type";export function OrchestratedPreviewScreen({configuration:t}){return r(d,{content:({navigationManager:e,onBack:o,onNavigateNext:c})=>{const u=s(e.configuration);if(e.currentPreviewIsDocument()){const m=e.currentDocumentPreviewPath();return r(l,{documentAspectRatio:e.documentFrameAspectRatio??f("Landscape"),showAttribution:u,...m!==void 0?{capturedDocumentPath:m,capturedDocumentBorderFraction:e.currentDocumentPreviewBorderFraction()}:{},onAccept:c,onReject:()=>{t.allowRetake&&(e.retakeCurrentDocumentSide(),o())},onClose:()=>e.exit()})}return r(p,{allowRetake:t.allowRetake,showAttribution:u,...e.selfieCaptureGeometry?{selfieCaptureGeometry:e.selfieCaptureGeometry}:{},...e.captured.selfiePath!==void 0?{capturedSelfiePath:e.captured.selfiePath}:{},onAccept:c,onReject:()=>{t.allowRetake&&o()}})}})}
|