idmission-web-sdk 2.6.1-changeset-release-develop-78d33ca → 2.6.1-changeset-release-develop-3d44875

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -901,6 +901,14 @@ type IdCaptureGuideImage = {
901
901
 
902
902
  type IdCaptureGuideType = 'fit' | 'overlay';
903
903
 
904
+ /**
905
+ * Why the camera could not be used: `permissionDenied` when the user or the
906
+ * browser refused the permission, `unavailable` when it could not be started
907
+ * (in use by another app, blocked by the OS, or no usable camera). Passed to
908
+ * `onCameraAccessDenied` so a host can word its own screen to match.
909
+ */
910
+ type CameraAccessDeniedReason = 'permissionDenied' | 'unavailable';
911
+
904
912
  type IdCaptureLoadingOverlayMode = 'default' | 'legacy' | 'ring';
905
913
 
906
914
  /** How the selfie guide prompts the user to put their head in the oval. */
@@ -8639,8 +8647,15 @@ type CompatCaptureExitProps = {
8639
8647
  * results in the cancel button being rendered on the loading overlay.
8640
8648
  */
8641
8649
  onUserCancel?: () => void;
8642
- /** Callback function that fires when the camera access is denied. */
8643
- onCameraAccessDenied?: () => void;
8650
+ /**
8651
+ * Callback function that fires when the camera cannot be used. `reason` is
8652
+ * `'permissionDenied'` when the user or browser refused camera permission,
8653
+ * or `'unavailable'` when the camera could not be started (in use by another
8654
+ * app, blocked by the operating system, or no usable camera found). In
8655
+ * VideoIdValidation it fires during ID capture only, not during the video
8656
+ * recording.
8657
+ */
8658
+ onCameraAccessDenied?: (reason: CameraAccessDeniedReason) => void;
8644
8659
  /** Callback function that fires when the camera tampering is detected. */
8645
8660
  onCameraTamperingDetected?: () => void;
8646
8661
  /**
@@ -11198,7 +11213,7 @@ declare global {
11198
11213
  var IDmissionSDK: IDmissionSDK;
11199
11214
  }
11200
11215
 
11201
- declare const webSdkVersion = "2.6.1-changeset-release-develop-78d33ca";
11216
+ declare const webSdkVersion = "2.6.1-changeset-release-develop-3d44875";
11202
11217
 
11203
11218
  /**
11204
11219
  * sdk2's imperative handle on the video-signature capture screen
@@ -11219,4 +11234,4 @@ type VideoSignatureCaptureRef = {
11219
11234
  };
11220
11235
 
11221
11236
  export { CapturedDocumentImg, CustomerBiometricsEnrollment, CustomerIdAndBiometricsEnrollment, CustomerIdentification, CustomerVerification, DocumentCapture, FaceValidation, IDmissionSDK, IdAndFaceValidation, IdValidation, SignatureKYC, VideoIdValidation, allowedAuthUrls, captureMediaIntegrity, createCaptureProgress, defaultAuthUrl, defaultSubmissionUrl, isObject, preloadModels, renderCustomerBiometricsEnrollment, renderCustomerIdAndBiometricsEnrollment, renderCustomerIdentification, renderCustomerVerification, renderDocumentCapture, renderFaceValidation, renderIdAndFaceValidation, renderIdValidation, renderSignatureKYC, renderVideoIdValidation, requiresSignatureRetry, setServerUrl, summarizeQualityWarning, themes, useDocumentUpload, webSdkVersion };
11222
- export type { CaptureProgressOptions, CaptureProgressSession, CaptureProgressTask, CustomerBiometricsEnrollmentAssets, CustomerBiometricsEnrollmentClassNames, CustomerBiometricsEnrollmentColors, CustomerBiometricsEnrollmentProps, CustomerBiometricsEnrollmentVerbiage, CustomerIdAndBiometricsEnrollmentAssets, CustomerIdAndBiometricsEnrollmentClassNames, CustomerIdAndBiometricsEnrollmentColors, CustomerIdAndBiometricsEnrollmentProps, CustomerIdAndBiometricsEnrollmentVerbiage, CustomerIdentificationAssets, CustomerIdentificationClassNames, CustomerIdentificationColors, CustomerIdentificationProps, CustomerIdentificationVerbiage, CustomerSuppliedVerbiage, CustomerVerificationAssets, CustomerVerificationClassNames, CustomerVerificationColors, CustomerVerificationProps, CustomerVerificationVerbiage, DocumentAutoCaptureOptions, DocumentAutoCaptureThresholds, DocumentCaptureClassNames, DocumentCaptureProps, DocumentCaptureVerbiage, DocumentMetadata, DocumentUploadHandlers, DocumentUploadProgressEvent, DocumentUploader, FaceValidationAssets, FaceValidationClassNames, FaceValidationColors, FaceValidationProps, FaceValidationVerbiage, FrameDecodeResult, FrameDecodeStatus, FrameProbeResult, IdAndFaceValidationAssets, IdAndFaceValidationCapturedDocumentType, IdAndFaceValidationClassNames, IdAndFaceValidationColors, IdAndFaceValidationExitReason, IdAndFaceValidationJourneyEvent, IdAndFaceValidationJourneyStage, IdAndFaceValidationProps, IdAndFaceValidationVerbiage, IdValidationAssets, IdValidationClassNames, IdValidationColors, IdValidationProps, IdValidationVerbiage, LoadingSpinnerComponent, LoadingSpinnerProps, LoadingSpinnerStage, MediaIntegrityToken, OnIdAndFaceValidationJourneyEvent, OnVideoSignatureCaptureAnalyzed, OnVideoSignatureCaptureAtRisk, QualityWarningSummary, RecordingInterruptedScreenProps, RemoteDiagnostics, SelfieCaptureQualityException, SelfieCaptureRecoveryOptions, SignatureKYCAssets, SignatureKYCClassNames, SignatureKYCColors, SignatureKYCProps, SignatureKYCVerbiage, SignatureMetricKey, SignatureValidityConfig, SignatureValidityConfigInput, SignatureValidityMetrics, SignatureValidityResult, SubmissionRequest, SubmissionResponse, Theme, UploadDocument, UseDocumentUploadOptions, VideoIdValidationAssets, VideoIdValidationClassNames, VideoIdValidationColors, VideoIdValidationProps, VideoIdValidationVerbiage, VideoSignatureCaptureRef, VideoSignatureMetadata, VideoSignatureQualitySignal, VideoSignatureQualityWarning, WorkflowObservation, WorkflowPhase };
11237
+ export type { CameraAccessDeniedReason, CaptureProgressOptions, CaptureProgressSession, CaptureProgressTask, CustomerBiometricsEnrollmentAssets, CustomerBiometricsEnrollmentClassNames, CustomerBiometricsEnrollmentColors, CustomerBiometricsEnrollmentProps, CustomerBiometricsEnrollmentVerbiage, CustomerIdAndBiometricsEnrollmentAssets, CustomerIdAndBiometricsEnrollmentClassNames, CustomerIdAndBiometricsEnrollmentColors, CustomerIdAndBiometricsEnrollmentProps, CustomerIdAndBiometricsEnrollmentVerbiage, CustomerIdentificationAssets, CustomerIdentificationClassNames, CustomerIdentificationColors, CustomerIdentificationProps, CustomerIdentificationVerbiage, CustomerSuppliedVerbiage, CustomerVerificationAssets, CustomerVerificationClassNames, CustomerVerificationColors, CustomerVerificationProps, CustomerVerificationVerbiage, DocumentAutoCaptureOptions, DocumentAutoCaptureThresholds, DocumentCaptureClassNames, DocumentCaptureProps, DocumentCaptureVerbiage, DocumentMetadata, DocumentUploadHandlers, DocumentUploadProgressEvent, DocumentUploader, FaceValidationAssets, FaceValidationClassNames, FaceValidationColors, FaceValidationProps, FaceValidationVerbiage, FrameDecodeResult, FrameDecodeStatus, FrameProbeResult, IdAndFaceValidationAssets, IdAndFaceValidationCapturedDocumentType, IdAndFaceValidationClassNames, IdAndFaceValidationColors, IdAndFaceValidationExitReason, IdAndFaceValidationJourneyEvent, IdAndFaceValidationJourneyStage, IdAndFaceValidationProps, IdAndFaceValidationVerbiage, IdValidationAssets, IdValidationClassNames, IdValidationColors, IdValidationProps, IdValidationVerbiage, LoadingSpinnerComponent, LoadingSpinnerProps, LoadingSpinnerStage, MediaIntegrityToken, OnIdAndFaceValidationJourneyEvent, OnVideoSignatureCaptureAnalyzed, OnVideoSignatureCaptureAtRisk, QualityWarningSummary, RecordingInterruptedScreenProps, RemoteDiagnostics, SelfieCaptureQualityException, SelfieCaptureRecoveryOptions, SignatureKYCAssets, SignatureKYCClassNames, SignatureKYCColors, SignatureKYCProps, SignatureKYCVerbiage, SignatureMetricKey, SignatureValidityConfig, SignatureValidityConfigInput, SignatureValidityMetrics, SignatureValidityResult, SubmissionRequest, SubmissionResponse, Theme, UploadDocument, UseDocumentUploadOptions, VideoIdValidationAssets, VideoIdValidationClassNames, VideoIdValidationColors, VideoIdValidationProps, VideoIdValidationVerbiage, VideoSignatureCaptureRef, VideoSignatureMetadata, VideoSignatureQualitySignal, VideoSignatureQualityWarning, WorkflowObservation, WorkflowPhase };
package/dist/props.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "$comment": "GENERATED by scripts/propsManifest.mjs at build time. Each customer flow's props, read off dist/index.d.ts.",
3
3
  "schemaVersion": 1,
4
- "version": "2.6.1-changeset-release-develop-78d33ca",
4
+ "version": "2.6.1-changeset-release-develop-3d44875",
5
5
  "components": {
6
6
  "IdValidation": {
7
7
  "description": "Render a fullscreen ID capture component that instructs the user to\nphotograph both sides of their ID card, or the full page of their passport.",
@@ -266,9 +266,9 @@
266
266
  },
267
267
  {
268
268
  "name": "onCameraAccessDenied",
269
- "type": "() => void",
269
+ "type": "(reason: CameraAccessDeniedReason) => void",
270
270
  "required": false,
271
- "description": "Callback function that fires when the camera access is denied."
271
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
272
272
  },
273
273
  {
274
274
  "name": "onCameraTamperingDetected",
@@ -949,9 +949,9 @@
949
949
  },
950
950
  {
951
951
  "name": "onCameraAccessDenied",
952
- "type": "() => void",
952
+ "type": "(reason: CameraAccessDeniedReason) => void",
953
953
  "required": false,
954
- "description": "Callback function that fires when the camera access is denied."
954
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
955
955
  },
956
956
  {
957
957
  "name": "onCameraTamperingDetected",
@@ -1452,9 +1452,9 @@
1452
1452
  },
1453
1453
  {
1454
1454
  "name": "onCameraAccessDenied",
1455
- "type": "() => void",
1455
+ "type": "(reason: CameraAccessDeniedReason) => void",
1456
1456
  "required": false,
1457
- "description": "Callback function that fires when the camera access is denied."
1457
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
1458
1458
  },
1459
1459
  {
1460
1460
  "name": "onCameraTamperingDetected",
@@ -2075,9 +2075,9 @@
2075
2075
  },
2076
2076
  {
2077
2077
  "name": "onCameraAccessDenied",
2078
- "type": "() => void",
2078
+ "type": "(reason: CameraAccessDeniedReason) => void",
2079
2079
  "required": false,
2080
- "description": "Callback function that fires when the camera access is denied."
2080
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
2081
2081
  },
2082
2082
  {
2083
2083
  "name": "onCameraTamperingDetected",
@@ -2728,9 +2728,9 @@
2728
2728
  },
2729
2729
  {
2730
2730
  "name": "onCameraAccessDenied",
2731
- "type": "() => void",
2731
+ "type": "(reason: CameraAccessDeniedReason) => void",
2732
2732
  "required": false,
2733
- "description": "Callback function that fires when the camera access is denied."
2733
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
2734
2734
  },
2735
2735
  {
2736
2736
  "name": "onCameraTamperingDetected",
@@ -3267,9 +3267,9 @@
3267
3267
  },
3268
3268
  {
3269
3269
  "name": "onCameraAccessDenied",
3270
- "type": "() => void",
3270
+ "type": "(reason: CameraAccessDeniedReason) => void",
3271
3271
  "required": false,
3272
- "description": "Callback function that fires when the camera access is denied."
3272
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
3273
3273
  },
3274
3274
  {
3275
3275
  "name": "onCameraTamperingDetected",
@@ -3584,9 +3584,9 @@
3584
3584
  },
3585
3585
  {
3586
3586
  "name": "onCameraAccessDenied",
3587
- "type": "() => void",
3587
+ "type": "(reason: CameraAccessDeniedReason) => void",
3588
3588
  "required": false,
3589
- "description": "Callback function that fires when the camera access is denied."
3589
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
3590
3590
  },
3591
3591
  {
3592
3592
  "name": "onCameraTamperingDetected",
@@ -4003,9 +4003,9 @@
4003
4003
  },
4004
4004
  {
4005
4005
  "name": "onCameraAccessDenied",
4006
- "type": "() => void",
4006
+ "type": "(reason: CameraAccessDeniedReason) => void",
4007
4007
  "required": false,
4008
- "description": "Callback function that fires when the camera access is denied."
4008
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
4009
4009
  },
4010
4010
  {
4011
4011
  "name": "onCameraTamperingDetected",
@@ -4434,9 +4434,9 @@
4434
4434
  },
4435
4435
  {
4436
4436
  "name": "onCameraAccessDenied",
4437
- "type": "() => void",
4437
+ "type": "(reason: CameraAccessDeniedReason) => void",
4438
4438
  "required": false,
4439
- "description": "Callback function that fires when the camera access is denied."
4439
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
4440
4440
  },
4441
4441
  {
4442
4442
  "name": "onCameraTamperingDetected",
@@ -4979,9 +4979,9 @@
4979
4979
  },
4980
4980
  {
4981
4981
  "name": "onCameraAccessDenied",
4982
- "type": "() => void",
4982
+ "type": "(reason: CameraAccessDeniedReason) => void",
4983
4983
  "required": false,
4984
- "description": "Callback function that fires when the camera access is denied."
4984
+ "description": "Callback function that fires when the camera cannot be used. `reason` is\n`'permissionDenied'` when the user or browser refused camera permission,\nor `'unavailable'` when the camera could not be started (in use by another\napp, blocked by the operating system, or no usable camera found). In\nVideoIdValidation it fires during ID capture only, not during the video\nrecording."
4985
4985
  },
4986
4986
  {
4987
4987
  "name": "onCameraTamperingDetected",
@@ -16402,7 +16402,7 @@ function _acquireCamera() {
16402
16402
  });
16403
16403
  case 8:
16404
16404
  if (stream) {
16405
- _context.next = 12;
16405
+ _context.next = 13;
16406
16406
  break;
16407
16407
  }
16408
16408
  _context.prev = 9;
@@ -16416,21 +16416,26 @@ function _acquireCamera() {
16416
16416
  debug$1(LOG_TAG + " opened fallback stream", {
16417
16417
  maxVideoResolution: maxVideoResolution
16418
16418
  });
16419
- _context.next = 12;
16419
+ _context.next = 13;
16420
16420
  break;
16421
16421
  case 11:
16422
16422
  _context.prev = 11;
16423
16423
  _t2 = _context["catch"](9);
16424
- // cameraStore.tsx:288-290 — non-fatal logging path, kept verbatim.
16425
- debug$1(LOG_TAG + " cannot open stream at all", _t2);
16424
+ if (!(_t2.name === 'NotAllowedError')) {
16425
+ _context.next = 12;
16426
+ break;
16427
+ }
16428
+ throw _t2;
16426
16429
  case 12:
16430
+ debug$1(LOG_TAG + " cannot open stream at all", _t2);
16431
+ case 13:
16427
16432
  if (stream) {
16428
- _context.next = 13;
16433
+ _context.next = 14;
16429
16434
  break;
16430
16435
  }
16431
16436
  error$1(LOG_TAG + " failed to open camera");
16432
16437
  throw new Error('failed to open camera: ');
16433
- case 13:
16438
+ case 14:
16434
16439
  debug$1(LOG_TAG + " camera access requested with constraints", constraints);
16435
16440
  handleStreamEnded = function handleStreamEnded() {
16436
16441
  // cameraStore.tsx:303-326 — sdk2 branches on whether a continuity
@@ -16453,7 +16458,7 @@ function _acquireCamera() {
16453
16458
  handleStreamEnded();
16454
16459
  };
16455
16460
  camera = obtainCameraAccess(stream, selectedCamera.label, videoEl);
16456
- _context.next = 14;
16461
+ _context.next = 15;
16457
16462
  return new Promise(function (resolve) {
16458
16463
  scheduleTimeout(function () {
16459
16464
  // iOS 17 has a strange behavior where the video track flickers
@@ -16469,7 +16474,7 @@ function _acquireCamera() {
16469
16474
  resolve();
16470
16475
  }, 500);
16471
16476
  });
16472
- case 14:
16477
+ case 15:
16473
16478
  isRearFacing = (_camera$isRearFacing = camera == null ? void 0 : camera.isRearFacing) != null ? _camera$isRearFacing : false;
16474
16479
  return _context.abrupt("return", {
16475
16480
  camera: camera,
@@ -16479,18 +16484,18 @@ function _acquireCamera() {
16479
16484
  return camera.release();
16480
16485
  }
16481
16486
  });
16482
- case 15:
16483
- _context.prev = 15;
16487
+ case 16:
16488
+ _context.prev = 16;
16484
16489
  _t3 = _context["catch"](2);
16485
16490
  if (!(_t3 instanceof CaptureAttachError)) {
16486
- _context.next = 16;
16491
+ _context.next = 17;
16487
16492
  break;
16488
16493
  }
16489
16494
  throw _t3;
16490
- case 16:
16495
+ case 17:
16491
16496
  err = _t3;
16492
16497
  if (!(err.name === 'NotAllowedError')) {
16493
- _context.next = 17;
16498
+ _context.next = 18;
16494
16499
  break;
16495
16500
  }
16496
16501
  // cameraStore.tsx:374-381 — outer catch's "blocked by the user" path.
@@ -16501,9 +16506,9 @@ function _acquireCamera() {
16501
16506
  code: 'CAMERA_PERMISSION_DENIED',
16502
16507
  recoverable: true
16503
16508
  });
16504
- case 17:
16509
+ case 18:
16505
16510
  if (!((_err$message = err.message) != null && _err$message.includes('failed to open camera') || (_err$message2 = err.message) != null && _err$message2.includes('Could not start video source'))) {
16506
- _context.next = 18;
16511
+ _context.next = 19;
16507
16512
  break;
16508
16513
  }
16509
16514
  error$1(LOG_TAG + " camera access encountered some other error", _t3);
@@ -16512,16 +16517,16 @@ function _acquireCamera() {
16512
16517
  recoverable: true,
16513
16518
  cause: _t3
16514
16519
  });
16515
- case 18:
16520
+ case 19:
16516
16521
  // cameraStore.tsx:382-385 — genuinely unexpected error; sdk2 rethrows it
16517
16522
  // as-is (no CaptureError bucket exists for it), so we do too.
16518
16523
  error$1(LOG_TAG + " camera access encountered some other error", _t3);
16519
16524
  throw _t3;
16520
- case 19:
16525
+ case 20:
16521
16526
  case "end":
16522
16527
  return _context.stop();
16523
16528
  }
16524
- }, _callee, null, [[2, 15], [5, 7], [9, 11]]);
16529
+ }, _callee, null, [[2, 16], [5, 7], [9, 11]]);
16525
16530
  }));
16526
16531
  return _acquireCamera.apply(this, arguments);
16527
16532
  }
@@ -20953,6 +20958,34 @@ var ErrorCard = styledComponents.styled(FlexCard)(_templateObject$A || (_templat
20953
20958
  var Heading$8 = styledComponents.styled.h1(_templateObject2$v || (_templateObject2$v = _taggedTemplateLiteralLoose(["\n font-size: 1.5rem;\n margin-top: 0;\n margin-bottom: 1rem;\n"])));
20954
20959
  var Description$2 = styledComponents.styled.p(_templateObject3$m || (_templateObject3$m = _taggedTemplateLiteralLoose(["\n line-height: 1.5;\n margin-bottom: 1.5rem;\n"])));
20955
20960
 
20961
+ function reasonFor(code) {
20962
+ if (code === 'CAMERA_PERMISSION_DENIED') return 'permissionDenied';
20963
+ if (code === 'CAMERA_UNAVAILABLE') return 'unavailable';
20964
+ return undefined;
20965
+ }
20966
+ /**
20967
+ * Calls `onCameraAccessDenied` once per camera failure a controller reports:
20968
+ * when its error code becomes one, changes to the other, or a different
20969
+ * controller reports one. Not per render, and not again when StrictMode
20970
+ * replays effects, since the latch only moves when what it saw changes. A
20971
+ * failure seen with no handler bound is not latched, so a handler bound later
20972
+ * still hears about it; one already reported stays latched while the handler
20973
+ * is briefly unbound.
20974
+ */
20975
+ function useCameraAccessDeniedReport(controller, errorCode, onCameraAccessDenied) {
20976
+ var reason = reasonFor(errorCode);
20977
+ var reportedRef = React.useRef(undefined);
20978
+ React.useEffect(function () {
20979
+ var reported = reportedRef.current;
20980
+ var alreadyReported = (reported == null ? void 0 : reported.controller) === controller && reported.reason === reason;
20981
+ reportedRef.current = {
20982
+ controller: controller,
20983
+ reason: onCameraAccessDenied || alreadyReported ? reason : undefined
20984
+ };
20985
+ if (reason && onCameraAccessDenied && !alreadyReported) onCameraAccessDenied(reason);
20986
+ }, [controller, reason, onCameraAccessDenied]);
20987
+ }
20988
+
20956
20989
  // The one file-read both fallback screens use.
20957
20990
  //
20958
20991
  // Shared rather than duplicated: they read the same kind of file for the same
@@ -21781,7 +21814,6 @@ function IdCaptureViewContent(_ref) {
21781
21814
  var pendingPrecapturedRef = React.useRef(new Set());
21782
21815
  var seenPrecapturedRef = React.useRef(new Set());
21783
21816
  var tamperReportedRef = React.useRef(false);
21784
- var cameraDeniedReportedRef = React.useRef(false);
21785
21817
  var reportedModelErrorRef = React.useRef(null);
21786
21818
  // A new controller is a new session, so every notification latch below has
21787
21819
  // to start over — the same reasoning as the attach and overlay-dismissal
@@ -21799,7 +21831,6 @@ function IdCaptureViewContent(_ref) {
21799
21831
  pendingPrecapturedRef.current = new Set();
21800
21832
  seenPrecapturedRef.current = new Set();
21801
21833
  tamperReportedRef.current = false;
21802
- cameraDeniedReportedRef.current = false;
21803
21834
  reportedModelErrorRef.current = null;
21804
21835
  }, [controller]);
21805
21836
  React.useEffect(function () {
@@ -21851,16 +21882,7 @@ function IdCaptureViewContent(_ref) {
21851
21882
  // controller's typed error, which is where core lands a denied camera and a
21852
21883
  // failed model load alike (dual-truth contract: the same failure is already
21853
21884
  // on screen, so these are notifications, not the error UI).
21854
- var cameraDenied = ((_state$error2 = state.error) == null ? void 0 : _state$error2.code) === 'CAMERA_PERMISSION_DENIED';
21855
- React.useEffect(function () {
21856
- if (!cameraDenied) {
21857
- cameraDeniedReportedRef.current = false;
21858
- return;
21859
- }
21860
- if (cameraDeniedReportedRef.current) return;
21861
- cameraDeniedReportedRef.current = true;
21862
- onCameraAccessDenied == null || onCameraAccessDenied();
21863
- }, [controller, cameraDenied, onCameraAccessDenied]);
21885
+ useCameraAccessDeniedReport(controller, (_state$error2 = state.error) == null ? void 0 : _state$error2.code, onCameraAccessDenied);
21864
21886
  // Keyed on the ERROR OBJECT's identity, not on its cause: a MODEL_LOAD_FAILED
21865
21887
  // with no cause attached is still a model failure the host asked to hear
21866
21888
  // about, and keying on the cause skipped those entirely. A second, different
@@ -27482,7 +27504,7 @@ var StyledButtonsRow$4 = styledComponents.styled(ButtonsRow$2)(_templateObject6$
27482
27504
 
27483
27505
  var _templateObject$p, _templateObject2$m;
27484
27506
  function SelfieCaptureSurface(_ref) {
27485
- var _state$error, _state$error2, _state$captureRecover, _state$error5, _state$captureRecover2, _state$prediction, _state$prediction$sam, _state$prediction2, _state$prediction3, _state$prediction4, _state$prediction5, _state$prediction6, _state$prediction7, _state$prediction8, _state$prediction9, _state$prediction0, _state$prediction1, _state$prediction$bri, _state$prediction10, _state$prediction$ran, _state$prediction11, _state$prediction$var, _state$prediction12, _assets$loadingOverla, _classNames$loadingOv, _colors$loadingOverla, _verbiage$loadingOver;
27507
+ var _state$error, _state$error2, _state$captureRecover, _state$error4, _state$error5, _state$captureRecover2, _state$prediction, _state$prediction$sam, _state$prediction2, _state$prediction3, _state$prediction4, _state$prediction5, _state$prediction6, _state$prediction7, _state$prediction8, _state$prediction9, _state$prediction0, _state$prediction1, _state$prediction$bri, _state$prediction10, _state$prediction$ran, _state$prediction11, _state$prediction$var, _state$prediction12, _assets$loadingOverla, _classNames$loadingOv, _colors$loadingOverla, _verbiage$loadingOver;
27486
27508
  var controller = _ref.controller,
27487
27509
  state = _ref.state,
27488
27510
  loadingOverlayMode = _ref.loadingOverlayMode,
@@ -27664,10 +27686,9 @@ function SelfieCaptureSurface(_ref) {
27664
27686
  kind: 'no-prompt'
27665
27687
  });
27666
27688
  var reportedModelErrorRef = React.useRef(null);
27667
- var cameraDeniedReportedRef = React.useRef(false);
27668
27689
  var tamperReportedRef = React.useRef(false);
27669
27690
  React.useEffect(function () {
27670
- var _state$error3, _state$error4;
27691
+ var _state$error3;
27671
27692
  var modelError = state.models.error;
27672
27693
  if (modelError && modelError !== reportedModelErrorRef.current) {
27673
27694
  reportedModelErrorRef.current = modelError;
@@ -27675,21 +27696,16 @@ function SelfieCaptureSurface(_ref) {
27675
27696
  onModelError == null || onModelError(modelError);
27676
27697
  }
27677
27698
  if (!modelError) reportedModelErrorRef.current = null;
27678
- var cameraDenied = ((_state$error3 = state.error) == null ? void 0 : _state$error3.code) === 'CAMERA_PERMISSION_DENIED';
27679
- if (cameraDenied && !cameraDeniedReportedRef.current) {
27680
- cameraDeniedReportedRef.current = true;
27681
- onCameraAccessDenied == null || onCameraAccessDenied();
27682
- }
27683
- if (!cameraDenied) cameraDeniedReportedRef.current = false;
27684
27699
  // Same one-shot latch as IdCaptureView's: the host counts detections, not
27685
27700
  // renders, and a cleared-then-re-detected tamper is a second detection.
27686
- var tampered = ((_state$error4 = state.error) == null ? void 0 : _state$error4.code) === 'CAMERA_TAMPERING_SUSPECTED';
27701
+ var tampered = ((_state$error3 = state.error) == null ? void 0 : _state$error3.code) === 'CAMERA_TAMPERING_SUSPECTED';
27687
27702
  if (tampered && !tamperReportedRef.current) {
27688
27703
  tamperReportedRef.current = true;
27689
27704
  onCameraTamperingDetected == null || onCameraTamperingDetected();
27690
27705
  }
27691
27706
  if (!tampered) tamperReportedRef.current = false;
27692
- }, [onCameraAccessDenied, onCameraTamperingDetected, onLoadingFailed, onModelError, (_state$error5 = state.error) == null ? void 0 : _state$error5.code, state.models.error]);
27707
+ }, [onCameraTamperingDetected, onLoadingFailed, onModelError, (_state$error4 = state.error) == null ? void 0 : _state$error4.code, state.models.error]);
27708
+ useCameraAccessDeniedReport(controller, (_state$error5 = state.error) == null ? void 0 : _state$error5.code, onCameraAccessDenied);
27693
27709
  var handleLoadingContinue = React.useCallback(function () {
27694
27710
  void controller.actions.start();
27695
27711
  onLoadingOverlayDismissed == null || onLoadingOverlayDismissed();
@@ -36387,7 +36403,7 @@ function DocumentCaptureView(props) {
36387
36403
  });
36388
36404
  }
36389
36405
  function DocumentCaptureSurface(_ref) {
36390
- var _entry$contentUrl, _entry$uploadState, _uiDocument$cameraFee, _entry$item$aspectRat, _uiDocument$instructi, _entry$item$title, _theme$documentCaptur, _theme$documentCaptur2, _state$autoCaptureShu, _state$autoCaptureShu2, _state$autoCaptureShu3, _state$autoCapture, _theme$documentCaptur3, _theme$documentCaptur4, _theme$colors$positiv, _theme$colors, _entry$item$title2, _entry$captureMetadat, _entry$captureMetadat2, _opaqueColor, _state$error, _state$error2, _guideRect$x, _guideRect$y, _guideRect$width, _guideRect$height, _state$autoCapture$gu, _state$autoCapture2;
36406
+ var _entry$contentUrl, _entry$uploadState, _uiDocument$cameraFee, _entry$item$aspectRat, _uiDocument$instructi, _entry$item$title, _theme$documentCaptur, _theme$documentCaptur2, _state$autoCaptureShu, _state$autoCaptureShu2, _state$autoCaptureShu3, _state$autoCapture, _theme$documentCaptur3, _theme$documentCaptur4, _theme$colors$positiv, _theme$colors, _entry$item$title2, _entry$captureMetadat, _entry$captureMetadat2, _opaqueColor, _state$error, _state$error2, _state$error3, _state$error4, _guideRect$x, _guideRect$y, _guideRect$width, _guideRect$height, _state$autoCapture$gu, _state$autoCapture2;
36391
36407
  var controller = _ref.controller,
36392
36408
  _ref$lang = _ref.lang,
36393
36409
  lang = _ref$lang === void 0 ? 'auto' : _ref$lang,
@@ -36616,20 +36632,13 @@ function DocumentCaptureSurface(_ref) {
36616
36632
  completedRef.current = true;
36617
36633
  onCompleted == null || onCompleted();
36618
36634
  }, [everyUploaded, onCompleted]);
36619
- var cameraAccessDenied = ((_state$error = state.error) == null ? void 0 : _state$error.code) === 'CAMERA_PERMISSION_DENIED';
36620
- var cameraTampered = ((_state$error2 = state.error) == null ? void 0 : _state$error2.code) === 'CAMERA_TAMPERING_SUSPECTED';
36621
- // Latched like the completion effect above: a notification per denial or
36622
- // detection, not per render.
36623
- var deniedReportedRef = React.useRef(false);
36624
- React.useEffect(function () {
36625
- if (!cameraAccessDenied) {
36626
- deniedReportedRef.current = false;
36627
- return;
36628
- }
36629
- if (deniedReportedRef.current) return;
36630
- deniedReportedRef.current = true;
36631
- onCameraAccessDenied == null || onCameraAccessDenied();
36632
- }, [cameraAccessDenied, onCameraAccessDenied]);
36635
+ // Either camera failure leaves the capture button stuck on "Loading", so
36636
+ // both get the retry button.
36637
+ var cameraFailed = ((_state$error = state.error) == null ? void 0 : _state$error.code) === 'CAMERA_PERMISSION_DENIED' || ((_state$error2 = state.error) == null ? void 0 : _state$error2.code) === 'CAMERA_UNAVAILABLE';
36638
+ var cameraTampered = ((_state$error3 = state.error) == null ? void 0 : _state$error3.code) === 'CAMERA_TAMPERING_SUSPECTED';
36639
+ // Latched like the completion effect above: a notification per camera
36640
+ // failure or detection, not per render.
36641
+ useCameraAccessDeniedReport(controller, (_state$error4 = state.error) == null ? void 0 : _state$error4.code, onCameraAccessDenied);
36633
36642
  var tamperReportedRef = React.useRef(false);
36634
36643
  React.useEffect(function () {
36635
36644
  if (!cameraTampered) {
@@ -36775,7 +36784,7 @@ function DocumentCaptureSurface(_ref) {
36775
36784
  finished: true,
36776
36785
  onClick: onExitAfterTamperSealPopped,
36777
36786
  children: verbiage.exitBtnText
36778
- }) : null : cameraAccessDenied ? jsxRuntime.jsx(LoaderButton, {
36787
+ }) : null : cameraFailed ? jsxRuntime.jsx(LoaderButton, {
36779
36788
  className: classNames.retryCameraAccessBtn,
36780
36789
  variant: "negative",
36781
36790
  finished: true,
@@ -48482,7 +48491,7 @@ function mapCustomerIdAndBiometricsEnrollmentProps(props, ctx) {
48482
48491
  });
48483
48492
  }
48484
48493
 
48485
- var webSdkVersion = '2.6.1-changeset-release-develop-78d33ca';
48494
+ var webSdkVersion = '2.6.1-changeset-release-develop-3d44875';
48486
48495
 
48487
48496
  // GENERATED by scripts/styleBagTypes.mjs from
48488
48497
  // src/__fixtures__/sdk2StyleBags.json and the mapper sweep — do not