Skip to content

Feature/jsonresults #150

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 17 commits into from
Closed

Feature/jsonresults #150

wants to merge 17 commits into from

Conversation

JNdhlovu
Copy link
Contributor

@JNdhlovu JNdhlovu commented Mar 20, 2025

User description

Story: https://app.shortcut.com/smileid/story/xxx

Summary

A few sentences/bullet points about the changes

Known Issues

Any shortcomings in your work. This may include corner cases not correctly handled or issues related
to but not within the scope of your PR. Design compromises should be discussed here if they were not
already discussed above.

Test Instructions

Concise test instructions on how to verify that your feature works as intended. This should include
changes to the development environment (if applicable) and all commands needed to run your work.

Screenshot

If applicable (e.g. UI changes), add screenshots to help explain your work.


PR Type

Enhancement


Description

  • Added skipApiSubmission flag for SmartSelfie™ capture

  • Made consent information optional in verification flows

  • Added useStrictMode for enhanced selfie capture

  • Updated JSON result handling for consistency


Changes walkthrough 📝

Relevant files
Enhancement
34 files
main.dart
Added useStrictMode parameter to SmileIDSmartSelfieCaptureView
+1/-0     
smile_id_biometric_kyc.dart
Renamed consent parameters for consistency                             
+2/-2     
smile_id_enhanced_document_verification.dart
Renamed consent parameters for consistency                             
+2/-2     
smile_id_smart_selfie_authentication_enhanced.dart
Added skipApiSubmission parameter                                               
+2/-0     
smile_id_smart_selfie_capture_view.dart
Added useStrictMode parameter                                                       
+2/-0     
smile_id_smart_selfie_enrollment_enhanced.dart
Added skipApiSubmission parameter                                               
+2/-0     
smileid_messages.g.dart
Updated auto-generated code for JSON handling                       
+615/-604
messages.dart
Made consentInformation optional and updated constructor 
+7/-6     
Mapper.kt
Updated enum mappings and added default consent                   
+42/-35 
SmileIDBiometricKYC.kt
Updated result handling with new JSON converters                 
+13/-16 
SmileIDDocumentCaptureView.kt
Updated to use new JSON result format                                       
+27/-18 
SmileIDDocumentVerification.kt
Updated to use new JSON result format                                       
+22/-17 
SmileIDEnhancedDocumentVerification.kt
Updated to use new JSON result format                                       
+21/-18 
SmileIDSmartSelfieAuthentication.kt
Added skipApiSubmission parameter and refactored                 
+4/-35   
SmileIDSmartSelfieCaptureView.kt
Refactored to use new result handling                                       
+52/-155
SmileIDSmartSelfieEnrollment.kt
Added skipApiSubmission parameter and refactored                 
+4/-35   
SmileSelfieComposablePlatformView.kt
Added new base class for selfie views                                       
+47/-0   
SmileIDSmartSelfieAuthenticationEnhanced.kt
Added skipApiSubmission parameter and refactored                 
+5/-37   
SmileIDSmartSelfieEnrollmentEnhanced.kt
Added skipApiSubmission parameter and refactored                 
+5/-37   
SmileIDMessages.g.kt
Updated auto-generated code for JSON handling                       
+2902/-2299
DocumentCaptureResult.kt
Removed in favor of unified result format                               
+0/-12   
SmartSelfieCaptureResult.kt
Removed in favor of unified result format                               
+0/-10   
SmileIDCaptureResult.kt
Added new unified result format                                                   
+63/-0   
DocumentCaptureResultAdapter.kt
Removed in favor of unified result format                               
+0/-106 
SelfieCaptureResultAdapter.kt
Removed in favor of unified result format                               
+0/-93   
Mapper.swift
Added default consent information handling                             
+16/-6   
SmileIDBiometricKYC.swift
Made consent information optional                                               
+6/-6     
SmileIDEnhancedDocumentVerification.swift
Made consent information optional                                               
+6/-6     
SmileIDMessages.g.swift
Updated auto-generated code for JSON handling                       
+537/-670
SmileIDSmartSelfieAuthentication.swift
Added skipApiSubmission parameter                                               
+1/-0     
SmileIDSmartSelfieAuthenticationEnhanced.swift
Added skipApiSubmission parameter                                               
+3/-0     
SmileIDSmartSelfieCaptureView.swift
Added useStrictMode and refactored                                             
+96/-89 
SmileIDSmartSelfieEnrollmentEnhanced.swift
Added skipApiSubmission parameter                                               
+3/-0     
pubspec.yaml
Bumped version to 10.3.5                                                                 
+1/-1     
Dependencies
1 files
smile_id.podspec
Updated iOS SDK version to 10.4.2                                               
+2/-2     
Documentation
2 files
CHANGELOG.md
Added release notes for version 10.3.5                                     
+15/-2   
README.md
Minor formatting improvements                                                       
+2/-4     

Need help?
  • Type /help how to ... in the comments thread for any questions about PR-Agent usage.
  • Check out the documentation for more information.
  • @JNdhlovu JNdhlovu requested a review from a team as a code owner March 20, 2025 10:16
    @prfectionist
    Copy link
    Contributor

    prfectionist bot commented Mar 20, 2025

    PR Reviewer Guide 🔍

    Here are some key observations to aid the review process:

    ⏱️ Estimated effort to review: 4 🔵🔵🔵🔵⚪
    🧪 No relevant tests
    🔒 No security concerns identified
    ⚡ Recommended focus areas for review

    Breaking Changes

    Major refactoring of message handling and encoding/decoding logic that could impact API compatibility and data serialization

    // Autogenerated from Pigeon (v16.0.5), do not edit directly.
    // See also: https://pub.dev/packages/pigeon
    // ignore_for_file: public_member_api_docs, non_constant_identifier_names, avoid_as, unused_import, unnecessary_parenthesis, prefer_null_aware_operators, omit_local_variable_types, unused_shown_name, unnecessary_import, no_leading_underscores_for_local_identifiers
    
    import 'dart:async';
    import 'dart:typed_data' show Float64List, Int32List, Int64List, Uint8List;
    
    import 'package:flutter/foundation.dart' show ReadBuffer, WriteBuffer;
    import 'package:flutter/services.dart';
    
    PlatformException _createConnectionError(String channelName) {
      return PlatformException(
        code: 'channel-error',
        message: 'Unable to establish connection on channel: "$channelName".',
      );
    }
    
    enum FlutterJobType {
      enhancedKyc,
      documentVerification,
      biometricKyc,
      enhancedDocumentVerification,
      smartSelfieEnrollment,
      smartSelfieAuthentication,
    }
    
    enum FlutterJobTypeV2 {
      smartSelfieAuthentication,
      smartSelfieEnrollment,
    }
    
    enum FlutterImageType {
      selfieJpgFile,
      idCardJpgFile,
      selfieJpgBase64,
      idCardJpgBase64,
      livenessJpgFile,
      idCardRearJpgFile,
      livenessJpgBase64,
      idCardRearJpgBase64,
    }
    
    enum FlutterActionResult {
      passed,
      completed,
      approved,
      verified,
      provisionallyApproved,
      returned,
      notReturned,
      failed,
      rejected,
      underReview,
      unableToDetermine,
      notApplicable,
      notVerified,
      notDone,
      issuerUnavailable,
      idAuthorityPhotoNotAvailable,
      sentToHumanReview,
      unknown,
    }
    
    enum FlutterSmartSelfieStatus {
      approved,
      pending,
      rejected,
      unknown,
    }
    
    class FlutterConsentInformation {
      FlutterConsentInformation({
        required this.consentGrantedDate,
        required this.personalDetailsConsentGranted,
        required this.contactInfoConsentGranted,
        required this.documentInfoConsentGranted,
      });
    
      String consentGrantedDate;
    
      bool personalDetailsConsentGranted;
    
      bool contactInfoConsentGranted;
    
      bool documentInfoConsentGranted;
    
      Object encode() {
        return <Object?>[
          consentGrantedDate,
          personalDetailsConsentGranted,
          contactInfoConsentGranted,
          documentInfoConsentGranted,
        ];
      }
    
      static FlutterConsentInformation decode(Object result) {
        result as List<Object?>;
        return FlutterConsentInformation(
          consentGrantedDate: result[0]! as String,
          personalDetailsConsentGranted: result[1]! as bool,
          contactInfoConsentGranted: result[2]! as bool,
          documentInfoConsentGranted: result[3]! as bool,
        );
      }
    }
    
    ///  Custom values specific to partners can be placed in [extras]
    class FlutterPartnerParams {
      FlutterPartnerParams({
        this.jobType,
        required this.jobId,
        required this.userId,
        this.extras,
      });
    
      FlutterJobType? jobType;
    
      String jobId;
    
      String userId;
    
      Map<String?, String?>? extras;
    
      Object encode() {
        return <Object?>[
          jobType?.index,
          jobId,
          userId,
          extras,
        ];
      }
    
      static FlutterPartnerParams decode(Object result) {
        result as List<Object?>;
        return FlutterPartnerParams(
          jobType: result[0] != null
              ? FlutterJobType.values[result[0]! as int]
              : null,
          jobId: result[1]! as String,
          userId: result[2]! as String,
          extras: (result[3] as Map<Object?, Object?>?)?.cast<String?, String?>(),
        );
      }
    }
    
    /// The Auth Smile request. Auth Smile serves multiple purposes:
    ///
    /// - It is used to fetch the signature needed for subsequent API requests
    /// - It indicates the type of job that will being performed
    /// - It is used to fetch consent information for the partner
    ///
    /// [jobType] The type of job that will be performed
    /// [country] The country code of the country where the job is being performed. This value is
    /// required in order to get back consent information for the partner
    /// [idType] The type of ID that will be used for the job. This value is required in order to
    /// get back consent information for the partner
    /// [updateEnrolledImage] Whether or not the enrolled image should be updated with image
    /// submitted for this job
    /// [jobId] The job ID to associate with the job. Most often, this will correspond to a unique
    /// Job ID within your own system. If not provided, a random job ID will be generated
    /// [userId] The user ID to associate with the job. Most often, this will correspond to a unique
    /// User ID within your own system. If not provided, a random user ID will be generated
    class FlutterAuthenticationRequest {
      FlutterAuthenticationRequest({
        required this.jobType,
        this.country,
        this.idType,
        this.updateEnrolledImage,
        this.jobId,
        this.userId,
      });
    
      FlutterJobType jobType;
    
      String? country;
    
      String? idType;
    
      bool? updateEnrolledImage;
    
      String? jobId;
    
      String? userId;
    
      Object encode() {
        return <Object?>[
          jobType.index,
          country,
          idType,
          updateEnrolledImage,
          jobId,
          userId,
        ];
      }
    
      static FlutterAuthenticationRequest decode(Object result) {
        result as List<Object?>;
        return FlutterAuthenticationRequest(
          jobType: FlutterJobType.values[result[0]! as int],
          country: result[1] as String?,
          idType: result[2] as String?,
          updateEnrolledImage: result[3] as bool?,
          jobId: result[4] as String?,
          userId: result[5] as String?,
        );
      }
    }
    
    /// [consentInfo] is only populated when a country and ID type are provided in the
    /// [FlutterAuthenticationRequest]. To get information about *all* countries and ID types instead,
    ///  [SmileIDService.getProductsConfig]
    ///
    /// [timestamp] is *not* a [DateTime] because technically, any arbitrary value could have been
    /// passed to it. This applies to all other timestamp fields in the SDK.
    class FlutterAuthenticationResponse {
      FlutterAuthenticationResponse({
        required this.success,
        required this.signature,
        required this.timestamp,
        required this.partnerParams,
        this.callbackUrl,
        this.consentInfo,
      });
    
      bool success;
    
      String signature;
    
      String timestamp;
    
      FlutterPartnerParams partnerParams;
    
      String? callbackUrl;
    
      FlutterConsentInfo? consentInfo;
    
      Object encode() {
        return <Object?>[
          success,
          signature,
          timestamp,
          partnerParams.encode(),
          callbackUrl,
          consentInfo?.encode(),
        ];
      }
    
      static FlutterAuthenticationResponse decode(Object result) {
        result as List<Object?>;
        return FlutterAuthenticationResponse(
          success: result[0]! as bool,
          signature: result[1]! as String,
          timestamp: result[2]! as String,
          partnerParams: FlutterPartnerParams.decode(result[3]! as List<Object?>),
          callbackUrl: result[4] as String?,
          consentInfo: result[5] != null
              ? FlutterConsentInfo.decode(result[5]! as List<Object?>)
              : null,
        );
      }
    }
    
    class FlutterPrepUploadRequest {
      FlutterPrepUploadRequest({
        required this.partnerParams,
        this.callbackUrl,
        required this.allowNewEnroll,
        required this.partnerId,
        required this.timestamp,
        required this.signature,
      });
    
      FlutterPartnerParams partnerParams;
    
      String? callbackUrl;
    
      bool allowNewEnroll;
    
      String partnerId;
    
      String timestamp;
    
      String signature;
    
      Object encode() {
        return <Object?>[
          partnerParams.encode(),
          callbackUrl,
          allowNewEnroll,
          partnerId,
          timestamp,
          signature,
        ];
      }
    
      static FlutterPrepUploadRequest decode(Object result) {
        result as List<Object?>;
        return FlutterPrepUploadRequest(
          partnerParams: FlutterPartnerParams.decode(result[0]! as List<Object?>),
          callbackUrl: result[1] as String?,
          allowNewEnroll: result[2]! as bool,
          partnerId: result[3]! as String,
          timestamp: result[4]! as String,
          signature: result[5]! as String,
        );
      }
    }
    
    class FlutterPrepUploadResponse {
      FlutterPrepUploadResponse({
        required this.code,
        required this.refId,
        required this.uploadUrl,
        required this.smileJobId,
      });
    
      String code;
    
      String refId;
    
      String uploadUrl;
    
      String smileJobId;
    
      Object encode() {
        return <Object?>[
          code,
          refId,
          uploadUrl,
          smileJobId,
        ];
      }
    
      static FlutterPrepUploadResponse decode(Object result) {
        result as List<Object?>;
        return FlutterPrepUploadResponse(
          code: result[0]! as String,
          refId: result[1]! as String,
          uploadUrl: result[2]! as String,
          smileJobId: result[3]! as String,
        );
      }
    }
    
    class FlutterUploadRequest {
      FlutterUploadRequest({
        required this.images,
        this.idInfo,
      });
    
      List<FlutterUploadImageInfo?> images;
    
      FlutterIdInfo? idInfo;
    
      Object encode() {
        return <Object?>[
          images,
          idInfo?.encode(),
        ];
      }
    
      static FlutterUploadRequest decode(Object result) {
        result as List<Object?>;
        return FlutterUploadRequest(
          images: (result[0] as List<Object?>?)!.cast<FlutterUploadImageInfo?>(),
          idInfo: result[1] != null
              ? FlutterIdInfo.decode(result[1]! as List<Object?>)
              : null,
        );
      }
    }
    
    class FlutterUploadImageInfo {
      FlutterUploadImageInfo({
        required this.imageTypeId,
        required this.imageName,
      });
    
      FlutterImageType imageTypeId;
    
      String imageName;
    
      Object encode() {
        return <Object?>[
          imageTypeId.index,
          imageName,
        ];
      }
    
      static FlutterUploadImageInfo decode(Object result) {
        result as List<Object?>;
        return FlutterUploadImageInfo(
          imageTypeId: FlutterImageType.values[result[0]! as int],
          imageName: result[1]! as String,
        );
      }
    }
    
    class FlutterIdInfo {
      FlutterIdInfo({
        required this.country,
        this.idType,
        this.idNumber,
        this.firstName,
        this.middleName,
        this.lastName,
        this.dob,
        this.bankCode,
        this.entered,
      });
    
      String country;
    
      String? idType;
    
      String? idNumber;
    
      String? firstName;
    
      String? middleName;
    
      String? lastName;
    
      String? dob;
    
      String? bankCode;
    
      bool? entered;
    
      Object encode() {
        return <Object?>[
          country,
          idType,
          idNumber,
          firstName,
          middleName,
          lastName,
          dob,
          bankCode,
          entered,
        ];
      }
    
      static FlutterIdInfo decode(Object result) {
        result as List<Object?>;
        return FlutterIdInfo(
          country: result[0]! as String,
          idType: result[1] as String?,
          idNumber: result[2] as String?,
          firstName: result[3] as String?,
          middleName: result[4] as String?,
          lastName: result[5] as String?,
          dob: result[6] as String?,
          bankCode: result[7] as String?,
          entered: result[8] as bool?,
        );
      }
    }
    
    class FlutterEnhancedKycResponse {
      FlutterEnhancedKycResponse({
        required this.smileJobId,
        required this.partnerParams,
        required this.resultText,
        required this.resultCode,
        required this.actions,
        required this.country,
        required this.idType,
        required this.idNumber,
        this.fullName,
        this.expirationDate,
        this.dob,
        this.base64Photo,
      });
    
      String smileJobId;
    
      FlutterPartnerParams partnerParams;
    
      String resultText;
    
      String resultCode;
    
      FlutterActions actions;
    
      String country;
    
      String idType;
    
      String idNumber;
    
      String? fullName;
    
      String? expirationDate;
    
      String? dob;
    
      String? base64Photo;
    
      Object encode() {
        return <Object?>[
          smileJobId,
          partnerParams.encode(),
          resultText,
          resultCode,
          actions.encode(),
          country,
          idType,
          idNumber,
          fullName,
          expirationDate,
          dob,
          base64Photo,
        ];
      }
    
      static FlutterEnhancedKycResponse decode(Object result) {
        result as List<Object?>;
        return FlutterEnhancedKycResponse(
          smileJobId: result[0]! as String,
          partnerParams: FlutterPartnerParams.decode(result[1]! as List<Object?>),
          resultText: result[2]! as String,
          resultCode: result[3]! as String,
          actions: FlutterActions.decode(result[4]! as List<Object?>),
          country: result[5]! as String,
          idType: result[6]! as String,
          idNumber: result[7]! as String,
          fullName: result[8] as String?,
          expirationDate: result[9] as String?,
          dob: result[10] as String?,
          base64Photo: result[11] as String?,
        );
      }
    }
    
    class FlutterActions {
      FlutterActions({
        required this.documentCheck,
        required this.humanReviewCompare,
        required this.humanReviewDocumentCheck,
        required this.humanReviewLivenessCheck,
        required this.humanReviewSelfieCheck,
        required this.humanReviewUpdateSelfie,
        required this.livenessCheck,
        required this.registerSelfie,
        required this.returnPersonalInfo,
        required this.selfieCheck,
        required this.selfieProvided,
        required this.selfieToIdAuthorityCompare,
        required this.selfieToIdCardCompare,
        required this.selfieToRegisteredSelfieCompare,
        required this.updateRegisteredSelfieOnFile,
        required this.verifyDocument,
        required this.verifyIdNumber,
      });
    
      FlutterActionResult documentCheck;
    
      FlutterActionResult humanReviewCompare;
    
      FlutterActionResult humanReviewDocumentCheck;
    
      FlutterActionResult humanReviewLivenessCheck;
    
      FlutterActionResult humanReviewSelfieCheck;
    
      FlutterActionResult humanReviewUpdateSelfie;
    
      FlutterActionResult livenessCheck;
    
      FlutterActionResult registerSelfie;
    
      FlutterActionResult returnPersonalInfo;
    
      FlutterActionResult selfieCheck;
    
      FlutterActionResult selfieProvided;
    
      FlutterActionResult selfieToIdAuthorityCompare;
    
      FlutterActionResult selfieToIdCardCompare;
    
      FlutterActionResult selfieToRegisteredSelfieCompare;
    
      FlutterActionResult updateRegisteredSelfieOnFile;
    
      FlutterActionResult verifyDocument;
    
      FlutterActionResult verifyIdNumber;
    
      Object encode() {
        return <Object?>[
          documentCheck.index,
          humanReviewCompare.index,
          humanReviewDocumentCheck.index,
          humanReviewLivenessCheck.index,
          humanReviewSelfieCheck.index,
          humanReviewUpdateSelfie.index,
          livenessCheck.index,
          registerSelfie.index,
          returnPersonalInfo.index,
          selfieCheck.index,
          selfieProvided.index,
          selfieToIdAuthorityCompare.index,
          selfieToIdCardCompare.index,
          selfieToRegisteredSelfieCompare.index,
          updateRegisteredSelfieOnFile.index,
          verifyDocument.index,
          verifyIdNumber.index,
        ];
      }
    
      static FlutterActions decode(Object result) {
        result as List<Object?>;
        return FlutterActions(
          documentCheck: FlutterActionResult.values[result[0]! as int],
          humanReviewCompare: FlutterActionResult.values[result[1]! as int],
          humanReviewDocumentCheck: FlutterActionResult.values[result[2]! as int],
          humanReviewLivenessCheck: FlutterActionResult.values[result[3]! as int],
          humanReviewSelfieCheck: FlutterActionResult.values[result[4]! as int],
          humanReviewUpdateSelfie: FlutterActionResult.values[result[5]! as int],
          livenessCheck: FlutterActionResult.values[result[6]! as int],
          registerSelfie: FlutterActionResult.values[result[7]! as int],
          returnPersonalInfo: FlutterActionResult.values[result[8]! as int],
          selfieCheck: FlutterActionResult.values[result[9]! as int],
          selfieProvided: FlutterActionResult.values[result[10]! as int],
          selfieToIdAuthorityCompare: FlutterActionResult.values[result[11]! as int],
          selfieToIdCardCompare: FlutterActionResult.values[result[12]! as int],
          selfieToRegisteredSelfieCompare: FlutterActionResult.values[result[13]! as int],
          updateRegisteredSelfieOnFile: FlutterActionResult.values[result[14]! as int],
          verifyDocument: FlutterActionResult.values[result[15]! as int],
          verifyIdNumber: FlutterActionResult.values[result[16]! as int],
        );
      }
    }
    Code Generation

    Significant changes to generated code including new message codec implementation and handling of enum values that needs validation

    // Autogenerated from Pigeon (v16.0.5), do not edit directly.
    // See also: https://pub.dev/packages/pigeon
    
    import android.util.Log
    import io.flutter.plugin.common.BasicMessageChannel
    import io.flutter.plugin.common.BinaryMessenger
    import io.flutter.plugin.common.MessageCodec
    import io.flutter.plugin.common.StandardMessageCodec
    import java.io.ByteArrayOutputStream
    import java.nio.ByteBuffer
    
    private fun wrapResult(result: Any?): List<Any?> = listOf(result)
    
    private fun wrapError(exception: Throwable): List<Any?> {
        if (exception is SmileFlutterError) {
            return listOf(
                exception.code,
                exception.message,
                exception.details,
            )
        } else {
            return listOf(
                exception.javaClass.simpleName,
                exception.toString(),
                "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception),
            )
        }
    }
    
    /**
     * Error class for passing custom error details to Flutter via a thrown PlatformException.
     * @property code The error code.
     * @property message The error message.
     * @property details The error details. Must be a datatype supported by the api codec.
     */
    class SmileFlutterError(
        val code: String,
        override val message: String? = null,
        val details: Any? = null,
    ) : Throwable()
    
    enum class FlutterJobType(
        val raw: Int,
    ) {
        ENHANCEDKYC(0),
        DOCUMENTVERIFICATION(1),
        BIOMETRICKYC(2),
        ENHANCEDDOCUMENTVERIFICATION(3),
        SMARTSELFIEENROLLMENT(4),
        SMARTSELFIEAUTHENTICATION(5),
        ;
    
        companion object {
            fun ofRaw(raw: Int): FlutterJobType? = values().firstOrNull { it.raw == raw }
        }
    }
    
    enum class FlutterJobTypeV2(
        val raw: Int,
    ) {
        SMARTSELFIEAUTHENTICATION(0),
        SMARTSELFIEENROLLMENT(1),
        ;
    
        companion object {
            fun ofRaw(raw: Int): FlutterJobTypeV2? = values().firstOrNull { it.raw == raw }
        }
    }
    
    enum class FlutterImageType(
        val raw: Int,
    ) {
        SELFIEJPGFILE(0),
        IDCARDJPGFILE(1),
        SELFIEJPGBASE64(2),
        IDCARDJPGBASE64(3),
        LIVENESSJPGFILE(4),
        IDCARDREARJPGFILE(5),
        LIVENESSJPGBASE64(6),
        IDCARDREARJPGBASE64(7),
        ;
    
        companion object {
            fun ofRaw(raw: Int): FlutterImageType? = values().firstOrNull { it.raw == raw }
        }
    }
    
    enum class FlutterActionResult(
        val raw: Int,
    ) {
        PASSED(0),
        COMPLETED(1),
        APPROVED(2),
        VERIFIED(3),
        PROVISIONALLYAPPROVED(4),
        RETURNED(5),
        NOTRETURNED(6),
        FAILED(7),
        REJECTED(8),
        UNDERREVIEW(9),
        UNABLETODETERMINE(10),
        NOTAPPLICABLE(11),
        NOTVERIFIED(12),
        NOTDONE(13),
        ISSUERUNAVAILABLE(14),
        IDAUTHORITYPHOTONOTAVAILABLE(15),
        SENTTOHUMANREVIEW(16),
        UNKNOWN(17),
        ;
    
        companion object {
            fun ofRaw(raw: Int): FlutterActionResult? = values().firstOrNull { it.raw == raw }
        }
    }
    
    enum class FlutterSmartSelfieStatus(
        val raw: Int,
    ) {
        APPROVED(0),
        PENDING(1),
        REJECTED(2),
        UNKNOWN(3),
        ;
    
        companion object {
            fun ofRaw(raw: Int): FlutterSmartSelfieStatus? = values().firstOrNull { it.raw == raw }
        }
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterConsentInformation(
        val consentGrantedDate: String,
        val personalDetailsConsentGranted: Boolean,
        val contactInfoConsentGranted: Boolean,
        val documentInfoConsentGranted: Boolean,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterConsentInformation {
                val consentGrantedDate = list[0] as String
                val personalDetailsConsentGranted = list[1] as Boolean
                val contactInfoConsentGranted = list[2] as Boolean
                val documentInfoConsentGranted = list[3] as Boolean
                return FlutterConsentInformation(
                    consentGrantedDate,
                    personalDetailsConsentGranted,
                    contactInfoConsentGranted,
                    documentInfoConsentGranted,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                consentGrantedDate,
                personalDetailsConsentGranted,
                contactInfoConsentGranted,
                documentInfoConsentGranted,
            )
    }
    
    /**
     *  Custom values specific to partners can be placed in [extras]
     *
     * Generated class from Pigeon that represents data sent in messages.
     */
    data class FlutterPartnerParams(
        val jobType: FlutterJobType? = null,
        val jobId: String,
        val userId: String,
        val extras: Map<String?, String?>? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterPartnerParams {
                val jobType: FlutterJobType? =
                    (list[0] as Int?)?.let {
                        FlutterJobType.ofRaw(it)
                    }
                val jobId = list[1] as String
                val userId = list[2] as String
                val extras = list[3] as Map<String?, String?>?
                return FlutterPartnerParams(jobType, jobId, userId, extras)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                jobType?.raw,
                jobId,
                userId,
                extras,
            )
    }
    
    /**
     * The Auth Smile request. Auth Smile serves multiple purposes:
     *
     * - It is used to fetch the signature needed for subsequent API requests
     * - It indicates the type of job that will being performed
     * - It is used to fetch consent information for the partner
     *
     * [jobType] The type of job that will be performed
     * [country] The country code of the country where the job is being performed. This value is
     * required in order to get back consent information for the partner
     * [idType] The type of ID that will be used for the job. This value is required in order to
     * get back consent information for the partner
     * [updateEnrolledImage] Whether or not the enrolled image should be updated with image
     * submitted for this job
     * [jobId] The job ID to associate with the job. Most often, this will correspond to a unique
     * Job ID within your own system. If not provided, a random job ID will be generated
     * [userId] The user ID to associate with the job. Most often, this will correspond to a unique
     * User ID within your own system. If not provided, a random user ID will be generated
     *
     * Generated class from Pigeon that represents data sent in messages.
     */
    data class FlutterAuthenticationRequest(
        val jobType: FlutterJobType,
        val country: String? = null,
        val idType: String? = null,
        val updateEnrolledImage: Boolean? = null,
        val jobId: String? = null,
        val userId: String? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterAuthenticationRequest {
                val jobType = FlutterJobType.ofRaw(list[0] as Int)!!
                val country = list[1] as String?
                val idType = list[2] as String?
                val updateEnrolledImage = list[3] as Boolean?
                val jobId = list[4] as String?
                val userId = list[5] as String?
                return FlutterAuthenticationRequest(
                    jobType,
                    country,
                    idType,
                    updateEnrolledImage,
                    jobId,
                    userId,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                jobType.raw,
                country,
                idType,
                updateEnrolledImage,
                jobId,
                userId,
            )
    }
    
    /**
     * [consentInfo] is only populated when a country and ID type are provided in the
     * [FlutterAuthenticationRequest]. To get information about *all* countries and ID types instead,
     *  [SmileIDService.getProductsConfig]
     *
     * [timestamp] is *not* a [DateTime] because technically, any arbitrary value could have been
     * passed to it. This applies to all other timestamp fields in the SDK.
     *
     * Generated class from Pigeon that represents data sent in messages.
     */
    data class FlutterAuthenticationResponse(
        val success: Boolean,
        val signature: String,
        val timestamp: String,
        val partnerParams: FlutterPartnerParams,
        val callbackUrl: String? = null,
        val consentInfo: FlutterConsentInfo? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterAuthenticationResponse {
                val success = list[0] as Boolean
                val signature = list[1] as String
                val timestamp = list[2] as String
                val partnerParams = FlutterPartnerParams.fromList(list[3] as List<Any?>)
                val callbackUrl = list[4] as String?
                val consentInfo: FlutterConsentInfo? =
                    (list[5] as List<Any?>?)?.let {
                        FlutterConsentInfo.fromList(it)
                    }
                return FlutterAuthenticationResponse(
                    success,
                    signature,
                    timestamp,
                    partnerParams,
                    callbackUrl,
                    consentInfo,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                success,
                signature,
                timestamp,
                partnerParams.toList(),
                callbackUrl,
                consentInfo?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterPrepUploadRequest(
        val partnerParams: FlutterPartnerParams,
        val callbackUrl: String? = null,
        val allowNewEnroll: Boolean,
        val partnerId: String,
        val timestamp: String,
        val signature: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterPrepUploadRequest {
                val partnerParams = FlutterPartnerParams.fromList(list[0] as List<Any?>)
                val callbackUrl = list[1] as String?
                val allowNewEnroll = list[2] as Boolean
                val partnerId = list[3] as String
                val timestamp = list[4] as String
                val signature = list[5] as String
                return FlutterPrepUploadRequest(
                    partnerParams,
                    callbackUrl,
                    allowNewEnroll,
                    partnerId,
                    timestamp,
                    signature,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                partnerParams.toList(),
                callbackUrl,
                allowNewEnroll,
                partnerId,
                timestamp,
                signature,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterPrepUploadResponse(
        val code: String,
        val refId: String,
        val uploadUrl: String,
        val smileJobId: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterPrepUploadResponse {
                val code = list[0] as String
                val refId = list[1] as String
                val uploadUrl = list[2] as String
                val smileJobId = list[3] as String
                return FlutterPrepUploadResponse(code, refId, uploadUrl, smileJobId)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                code,
                refId,
                uploadUrl,
                smileJobId,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterUploadRequest(
        val images: List<FlutterUploadImageInfo?>,
        val idInfo: FlutterIdInfo? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterUploadRequest {
                val images = list[0] as List<FlutterUploadImageInfo?>
                val idInfo: FlutterIdInfo? =
                    (list[1] as List<Any?>?)?.let {
                        FlutterIdInfo.fromList(it)
                    }
                return FlutterUploadRequest(images, idInfo)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                images,
                idInfo?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterUploadImageInfo(
        val imageTypeId: FlutterImageType,
        val imageName: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterUploadImageInfo {
                val imageTypeId = FlutterImageType.ofRaw(list[0] as Int)!!
                val imageName = list[1] as String
                return FlutterUploadImageInfo(imageTypeId, imageName)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                imageTypeId.raw,
                imageName,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterIdInfo(
        val country: String,
        val idType: String? = null,
        val idNumber: String? = null,
        val firstName: String? = null,
        val middleName: String? = null,
        val lastName: String? = null,
        val dob: String? = null,
        val bankCode: String? = null,
        val entered: Boolean? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterIdInfo {
                val country = list[0] as String
                val idType = list[1] as String?
                val idNumber = list[2] as String?
                val firstName = list[3] as String?
                val middleName = list[4] as String?
                val lastName = list[5] as String?
                val dob = list[6] as String?
                val bankCode = list[7] as String?
                val entered = list[8] as Boolean?
                return FlutterIdInfo(
                    country,
                    idType,
                    idNumber,
                    firstName,
                    middleName,
                    lastName,
                    dob,
                    bankCode,
                    entered,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                country,
                idType,
                idNumber,
                firstName,
                middleName,
                lastName,
                dob,
                bankCode,
                entered,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterEnhancedKycResponse(
        val smileJobId: String,
        val partnerParams: FlutterPartnerParams,
        val resultText: String,
        val resultCode: String,
        val actions: FlutterActions,
        val country: String,
        val idType: String,
        val idNumber: String,
        val fullName: String? = null,
        val expirationDate: String? = null,
        val dob: String? = null,
        val base64Photo: String? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterEnhancedKycResponse {
                val smileJobId = list[0] as String
                val partnerParams = FlutterPartnerParams.fromList(list[1] as List<Any?>)
                val resultText = list[2] as String
                val resultCode = list[3] as String
                val actions = FlutterActions.fromList(list[4] as List<Any?>)
                val country = list[5] as String
                val idType = list[6] as String
                val idNumber = list[7] as String
                val fullName = list[8] as String?
                val expirationDate = list[9] as String?
                val dob = list[10] as String?
                val base64Photo = list[11] as String?
                return FlutterEnhancedKycResponse(
                    smileJobId,
                    partnerParams,
                    resultText,
                    resultCode,
                    actions,
                    country,
                    idType,
                    idNumber,
                    fullName,
                    expirationDate,
                    dob,
                    base64Photo,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                smileJobId,
                partnerParams.toList(),
                resultText,
                resultCode,
                actions.toList(),
                country,
                idType,
                idNumber,
                fullName,
                expirationDate,
                dob,
                base64Photo,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterActions(
        val documentCheck: FlutterActionResult,
        val humanReviewCompare: FlutterActionResult,
        val humanReviewDocumentCheck: FlutterActionResult,
        val humanReviewLivenessCheck: FlutterActionResult,
        val humanReviewSelfieCheck: FlutterActionResult,
        val humanReviewUpdateSelfie: FlutterActionResult,
        val livenessCheck: FlutterActionResult,
        val registerSelfie: FlutterActionResult,
        val returnPersonalInfo: FlutterActionResult,
        val selfieCheck: FlutterActionResult,
        val selfieProvided: FlutterActionResult,
        val selfieToIdAuthorityCompare: FlutterActionResult,
        val selfieToIdCardCompare: FlutterActionResult,
        val selfieToRegisteredSelfieCompare: FlutterActionResult,
        val updateRegisteredSelfieOnFile: FlutterActionResult,
        val verifyDocument: FlutterActionResult,
        val verifyIdNumber: FlutterActionResult,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterActions {
                val documentCheck = FlutterActionResult.ofRaw(list[0] as Int)!!
                val humanReviewCompare = FlutterActionResult.ofRaw(list[1] as Int)!!
                val humanReviewDocumentCheck = FlutterActionResult.ofRaw(list[2] as Int)!!
                val humanReviewLivenessCheck = FlutterActionResult.ofRaw(list[3] as Int)!!
                val humanReviewSelfieCheck = FlutterActionResult.ofRaw(list[4] as Int)!!
                val humanReviewUpdateSelfie = FlutterActionResult.ofRaw(list[5] as Int)!!
                val livenessCheck = FlutterActionResult.ofRaw(list[6] as Int)!!
                val registerSelfie = FlutterActionResult.ofRaw(list[7] as Int)!!
                val returnPersonalInfo = FlutterActionResult.ofRaw(list[8] as Int)!!
                val selfieCheck = FlutterActionResult.ofRaw(list[9] as Int)!!
                val selfieProvided = FlutterActionResult.ofRaw(list[10] as Int)!!
                val selfieToIdAuthorityCompare = FlutterActionResult.ofRaw(list[11] as Int)!!
                val selfieToIdCardCompare = FlutterActionResult.ofRaw(list[12] as Int)!!
                val selfieToRegisteredSelfieCompare = FlutterActionResult.ofRaw(list[13] as Int)!!
                val updateRegisteredSelfieOnFile = FlutterActionResult.ofRaw(list[14] as Int)!!
                val verifyDocument = FlutterActionResult.ofRaw(list[15] as Int)!!
                val verifyIdNumber = FlutterActionResult.ofRaw(list[16] as Int)!!
                return FlutterActions(
                    documentCheck,
                    humanReviewCompare,
                    humanReviewDocumentCheck,
                    humanReviewLivenessCheck,
                    humanReviewSelfieCheck,
                    humanReviewUpdateSelfie,
                    livenessCheck,
                    registerSelfie,
                    returnPersonalInfo,
                    selfieCheck,
                    selfieProvided,
                    selfieToIdAuthorityCompare,
                    selfieToIdCardCompare,
                    selfieToRegisteredSelfieCompare,
                    updateRegisteredSelfieOnFile,
                    verifyDocument,
                    verifyIdNumber,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                documentCheck.raw,
                humanReviewCompare.raw,
                humanReviewDocumentCheck.raw,
                humanReviewLivenessCheck.raw,
                humanReviewSelfieCheck.raw,
                humanReviewUpdateSelfie.raw,
                livenessCheck.raw,
                registerSelfie.raw,
                returnPersonalInfo.raw,
                selfieCheck.raw,
                selfieProvided.raw,
                selfieToIdAuthorityCompare.raw,
                selfieToIdCardCompare.raw,
                selfieToRegisteredSelfieCompare.raw,
                updateRegisteredSelfieOnFile.raw,
                verifyDocument.raw,
                verifyIdNumber.raw,
            )
    }
    
    /**
     * [canAccess] Whether or not the ID type is enabled for the partner
     * [consentRequired] Whether or not consent is required for the ID type
     *
     * Generated class from Pigeon that represents data sent in messages.
     */
    data class FlutterConsentInfo(
        val canAccess: Boolean,
        val consentRequired: Boolean,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterConsentInfo {
                val canAccess = list[0] as Boolean
                val consentRequired = list[1] as Boolean
                return FlutterConsentInfo(canAccess, consentRequired)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                canAccess,
                consentRequired,
            )
    }
    
    /**
     * [timestamp] is *not* a [DateTime] because technically, any arbitrary value could have been
     * passed to it. This applies to all other timestamp fields in the SDK.
     *
     * Generated class from Pigeon that represents data sent in messages.
     */
    data class FlutterEnhancedKycRequest(
        val country: String,
        val idType: String,
        val idNumber: String,
        val firstName: String? = null,
        val middleName: String? = null,
        val lastName: String? = null,
        val dob: String? = null,
        val phoneNumber: String? = null,
        val bankCode: String? = null,
        val callbackUrl: String? = null,
        val partnerParams: FlutterPartnerParams,
        val timestamp: String,
        val signature: String,
        val consentInformation: FlutterConsentInformation? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterEnhancedKycRequest {
                val country = list[0] as String
                val idType = list[1] as String
                val idNumber = list[2] as String
                val firstName = list[3] as String?
                val middleName = list[4] as String?
                val lastName = list[5] as String?
                val dob = list[6] as String?
                val phoneNumber = list[7] as String?
                val bankCode = list[8] as String?
                val callbackUrl = list[9] as String?
                val partnerParams = FlutterPartnerParams.fromList(list[10] as List<Any?>)
                val timestamp = list[11] as String
                val signature = list[12] as String
                val consentInformation: FlutterConsentInformation? =
                    (list[13] as List<Any?>?)?.let {
                        FlutterConsentInformation.fromList(it)
                    }
                return FlutterEnhancedKycRequest(
                    country,
                    idType,
                    idNumber,
                    firstName,
                    middleName,
                    lastName,
                    dob,
                    phoneNumber,
                    bankCode,
                    callbackUrl,
                    partnerParams,
                    timestamp,
                    signature,
                    consentInformation,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                country,
                idType,
                idNumber,
                firstName,
                middleName,
                lastName,
                dob,
                phoneNumber,
                bankCode,
                callbackUrl,
                partnerParams.toList(),
                timestamp,
                signature,
                consentInformation?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterEnhancedKycAsyncResponse(
        val success: Boolean,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterEnhancedKycAsyncResponse {
                val success = list[0] as Boolean
                return FlutterEnhancedKycAsyncResponse(success)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                success,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterImageLinks(
        val selfieImageUrl: String? = null,
        val error: String? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterImageLinks {
                val selfieImageUrl = list[0] as String?
                val error = list[1] as String?
                return FlutterImageLinks(selfieImageUrl, error)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                selfieImageUrl,
                error,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterAntifraud(
        val suspectUsers: List<FlutterSuspectUser?>,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterAntifraud {
                val suspectUsers = list[0] as List<FlutterSuspectUser?>
                return FlutterAntifraud(suspectUsers)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                suspectUsers,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterSuspectUser(
        val reason: String,
        val userId: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterSuspectUser {
                val reason = list[0] as String
                val userId = list[1] as String
                return FlutterSuspectUser(reason, userId)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                reason,
                userId,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterJobStatusRequest(
        val userId: String,
        val jobId: String,
        val includeImageLinks: Boolean,
        val includeHistory: Boolean,
        val partnerId: String,
        val timestamp: String,
        val signature: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterJobStatusRequest {
                val userId = list[0] as String
                val jobId = list[1] as String
                val includeImageLinks = list[2] as Boolean
                val includeHistory = list[3] as Boolean
                val partnerId = list[4] as String
                val timestamp = list[5] as String
                val signature = list[6] as String
                return FlutterJobStatusRequest(
                    userId,
                    jobId,
                    includeImageLinks,
                    includeHistory,
                    partnerId,
                    timestamp,
                    signature,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                userId,
                jobId,
                includeImageLinks,
                includeHistory,
                partnerId,
                timestamp,
                signature,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterSmartSelfieJobResult(
        val actions: FlutterActions,
        val resultCode: String,
        val resultText: String,
        val smileJobId: String,
        val partnerParams: FlutterPartnerParams,
        val confidence: Double? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterSmartSelfieJobResult {
                val actions = FlutterActions.fromList(list[0] as List<Any?>)
                val resultCode = list[1] as String
                val resultText = list[2] as String
                val smileJobId = list[3] as String
                val partnerParams = FlutterPartnerParams.fromList(list[4] as List<Any?>)
                val confidence = list[5] as Double?
                return FlutterSmartSelfieJobResult(
                    actions,
                    resultCode,
                    resultText,
                    smileJobId,
                    partnerParams,
                    confidence,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                actions.toList(),
                resultCode,
                resultText,
                smileJobId,
                partnerParams.toList(),
                confidence,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterSmartSelfieJobStatusResponse(
        val timestamp: String,
        val jobComplete: Boolean,
        val jobSuccess: Boolean,
        val code: String,
        val result: FlutterSmartSelfieJobResult? = null,
        val resultString: String? = null,
        val history: List<FlutterSmartSelfieJobResult?>? = null,
        val imageLinks: FlutterImageLinks? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterSmartSelfieJobStatusResponse {
                val timestamp = list[0] as String
                val jobComplete = list[1] as Boolean
                val jobSuccess = list[2] as Boolean
                val code = list[3] as String
                val result: FlutterSmartSelfieJobResult? =
                    (list[4] as List<Any?>?)?.let {
                        FlutterSmartSelfieJobResult.fromList(it)
                    }
                val resultString = list[5] as String?
                val history = list[6] as List<FlutterSmartSelfieJobResult?>?
                val imageLinks: FlutterImageLinks? =
                    (list[7] as List<Any?>?)?.let {
                        FlutterImageLinks.fromList(it)
                    }
                return FlutterSmartSelfieJobStatusResponse(
                    timestamp,
                    jobComplete,
                    jobSuccess,
                    code,
                    result,
                    resultString,
                    history,
                    imageLinks,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                timestamp,
                jobComplete,
                jobSuccess,
                code,
                result?.toList(),
                resultString,
                history,
                imageLinks?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterSmartSelfieResponse(
        val code: String,
        val createdAt: String,
        val jobId: String,
        val jobType: FlutterJobTypeV2,
        val message: String,
        val partnerId: String,
        val partnerParams: Map<String?, String?>? = null,
        val status: FlutterSmartSelfieStatus,
        val updatedAt: String,
        val userId: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterSmartSelfieResponse {
                val code = list[0] as String
                val createdAt = list[1] as String
                val jobId = list[2] as String
                val jobType = FlutterJobTypeV2.ofRaw(list[3] as Int)!!
                val message = list[4] as String
                val partnerId = list[5] as String
                val partnerParams = list[6] as Map<String?, String?>?
                val status = FlutterSmartSelfieStatus.ofRaw(list[7] as Int)!!
                val updatedAt = list[8] as String
                val userId = list[9] as String
                return FlutterSmartSelfieResponse(
                    code,
                    createdAt,
                    jobId,
                    jobType,
                    message,
                    partnerId,
                    partnerParams,
                    status,
                    updatedAt,
                    userId,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                code,
                createdAt,
                jobId,
                jobType.raw,
                message,
                partnerId,
                partnerParams,
                status.raw,
                updatedAt,
                userId,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterDocumentVerificationJobResult(
        val actions: FlutterActions,
        val resultCode: String,
        val resultText: String,
        val smileJobId: String,
        val partnerParams: FlutterPartnerParams,
        val country: String? = null,
        val idType: String? = null,
        val idNumber: String? = null,
        val fullName: String? = null,
        val dob: String? = null,
        val gender: String? = null,
        val expirationDate: String? = null,
        val documentImageBase64: String? = null,
        val phoneNumber: String? = null,
        val phoneNumber2: String? = null,
        val address: String? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterDocumentVerificationJobResult {
                val actions = FlutterActions.fromList(list[0] as List<Any?>)
                val resultCode = list[1] as String
                val resultText = list[2] as String
                val smileJobId = list[3] as String
                val partnerParams = FlutterPartnerParams.fromList(list[4] as List<Any?>)
                val country = list[5] as String?
                val idType = list[6] as String?
                val idNumber = list[7] as String?
                val fullName = list[8] as String?
                val dob = list[9] as String?
                val gender = list[10] as String?
                val expirationDate = list[11] as String?
                val documentImageBase64 = list[12] as String?
                val phoneNumber = list[13] as String?
                val phoneNumber2 = list[14] as String?
                val address = list[15] as String?
                return FlutterDocumentVerificationJobResult(
                    actions,
                    resultCode,
                    resultText,
                    smileJobId,
                    partnerParams,
                    country,
                    idType,
                    idNumber,
                    fullName,
                    dob,
                    gender,
                    expirationDate,
                    documentImageBase64,
                    phoneNumber,
                    phoneNumber2,
                    address,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                actions.toList(),
                resultCode,
                resultText,
                smileJobId,
                partnerParams.toList(),
                country,
                idType,
                idNumber,
                fullName,
                dob,
                gender,
                expirationDate,
                documentImageBase64,
                phoneNumber,
                phoneNumber2,
                address,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterDocumentVerificationJobStatusResponse(
        val timestamp: String,
        val jobComplete: Boolean,
        val jobSuccess: Boolean,
        val code: String,
        val result: FlutterDocumentVerificationJobResult? = null,
        val resultString: String? = null,
        val history: List<FlutterDocumentVerificationJobResult?>? = null,
        val imageLinks: FlutterImageLinks? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterDocumentVerificationJobStatusResponse {
                val timestamp = list[0] as String
                val jobComplete = list[1] as Boolean
                val jobSuccess = list[2] as Boolean
                val code = list[3] as String
                val result: FlutterDocumentVerificationJobResult? =
                    (list[4] as List<Any?>?)?.let {
                        FlutterDocumentVerificationJobResult.fromList(it)
                    }
                val resultString = list[5] as String?
                val history = list[6] as List<FlutterDocumentVerificationJobResult?>?
                val imageLinks: FlutterImageLinks? =
                    (list[7] as List<Any?>?)?.let {
                        FlutterImageLinks.fromList(it)
                    }
                return FlutterDocumentVerificationJobStatusResponse(
                    timestamp,
                    jobComplete,
                    jobSuccess,
                    code,
                    result,
                    resultString,
                    history,
                    imageLinks,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                timestamp,
                jobComplete,
                jobSuccess,
                code,
                result?.toList(),
                resultString,
                history,
                imageLinks?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterBiometricKycJobResult(
        val actions: FlutterActions,
        val resultCode: String,
        val resultText: String,
        val resultType: String,
        val smileJobId: String,
        val partnerParams: FlutterPartnerParams,
        val antifraud: FlutterAntifraud? = null,
        val dob: String? = null,
        val photoBase64: String? = null,
        val gender: String? = null,
        val idType: String? = null,
        val address: String? = null,
        val country: String? = null,
        val documentImageBase64: String? = null,
        val fullData: Map<String?, String?>? = null,
        val fullName: String? = null,
        val idNumber: String? = null,
        val phoneNumber: String? = null,
        val phoneNumber2: String? = null,
        val expirationDate: String? = null,
        val secondaryIdNumber: String? = null,
        val idNumberPreviouslyRegistered: Boolean? = null,
        val previousRegistrantsUserIds: List<String?>? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterBiometricKycJobResult {
                val actions = FlutterActions.fromList(list[0] as List<Any?>)
                val resultCode = list[1] as String
                val resultText = list[2] as String
                val resultType = list[3] as String
                val smileJobId = list[4] as String
                val partnerParams = FlutterPartnerParams.fromList(list[5] as List<Any?>)
                val antifraud: FlutterAntifraud? =
                    (list[6] as List<Any?>?)?.let {
                        FlutterAntifraud.fromList(it)
                    }
                val dob = list[7] as String?
                val photoBase64 = list[8] as String?
                val gender = list[9] as String?
                val idType = list[10] as String?
                val address = list[11] as String?
                val country = list[12] as String?
                val documentImageBase64 = list[13] as String?
                val fullData = list[14] as Map<String?, String?>?
                val fullName = list[15] as String?
                val idNumber = list[16] as String?
                val phoneNumber = list[17] as String?
                val phoneNumber2 = list[18] as String?
                val expirationDate = list[19] as String?
                val secondaryIdNumber = list[20] as String?
                val idNumberPreviouslyRegistered = list[21] as Boolean?
                val previousRegistrantsUserIds = list[22] as List<String?>?
                return FlutterBiometricKycJobResult(
                    actions,
                    resultCode,
                    resultText,
                    resultType,
                    smileJobId,
                    partnerParams,
                    antifraud,
                    dob,
                    photoBase64,
                    gender,
                    idType,
                    address,
                    country,
                    documentImageBase64,
                    fullData,
                    fullName,
                    idNumber,
                    phoneNumber,
                    phoneNumber2,
                    expirationDate,
                    secondaryIdNumber,
                    idNumberPreviouslyRegistered,
                    previousRegistrantsUserIds,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                actions.toList(),
                resultCode,
                resultText,
                resultType,
                smileJobId,
                partnerParams.toList(),
                antifraud?.toList(),
                dob,
                photoBase64,
                gender,
                idType,
                address,
                country,
                documentImageBase64,
                fullData,
                fullName,
                idNumber,
                phoneNumber,
                phoneNumber2,
                expirationDate,
                secondaryIdNumber,
                idNumberPreviouslyRegistered,
                previousRegistrantsUserIds,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterBiometricKycJobStatusResponse(
        val timestamp: String,
        val jobComplete: Boolean,
        val jobSuccess: Boolean,
        val code: String,
        val result: FlutterBiometricKycJobResult? = null,
        val resultString: String? = null,
        val history: List<FlutterBiometricKycJobResult?>? = null,
        val imageLinks: FlutterImageLinks? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterBiometricKycJobStatusResponse {
                val timestamp = list[0] as String
                val jobComplete = list[1] as Boolean
                val jobSuccess = list[2] as Boolean
                val code = list[3] as String
                val result: FlutterBiometricKycJobResult? =
                    (list[4] as List<Any?>?)?.let {
                        FlutterBiometricKycJobResult.fromList(it)
                    }
                val resultString = list[5] as String?
                val history = list[6] as List<FlutterBiometricKycJobResult?>?
                val imageLinks: FlutterImageLinks? =
                    (list[7] as List<Any?>?)?.let {
                        FlutterImageLinks.fromList(it)
                    }
                return FlutterBiometricKycJobStatusResponse(
                    timestamp,
                    jobComplete,
                    jobSuccess,
                    code,
                    result,
                    resultString,
                    history,
                    imageLinks,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                timestamp,
                jobComplete,
                jobSuccess,
                code,
                result?.toList(),
                resultString,
                history,
                imageLinks?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterEnhancedDocumentVerificationJobResult(
        val actions: FlutterActions,
        val resultCode: String,
        val resultText: String,
        val resultType: String,
        val smileJobId: String,
        val partnerParams: FlutterPartnerParams,
        val antifraud: FlutterAntifraud? = null,
        val dob: String? = null,
        val photoBase64: String? = null,
        val gender: String? = null,
        val idType: String? = null,
        val address: String? = null,
        val country: String? = null,
        val documentImageBase64: String? = null,
        val fullData: Map<String?, String?>? = null,
        val fullName: String? = null,
        val idNumber: String? = null,
        val phoneNumber: String? = null,
        val phoneNumber2: String? = null,
        val expirationDate: String? = null,
        val secondaryIdNumber: String? = null,
        val idNumberPreviouslyRegistered: Boolean? = null,
        val previousRegistrantsUserIds: List<String?>? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterEnhancedDocumentVerificationJobResult {
                val actions = FlutterActions.fromList(list[0] as List<Any?>)
                val resultCode = list[1] as String
                val resultText = list[2] as String
                val resultType = list[3] as String
                val smileJobId = list[4] as String
                val partnerParams = FlutterPartnerParams.fromList(list[5] as List<Any?>)
                val antifraud: FlutterAntifraud? =
                    (list[6] as List<Any?>?)?.let {
                        FlutterAntifraud.fromList(it)
                    }
                val dob = list[7] as String?
                val photoBase64 = list[8] as String?
                val gender = list[9] as String?
                val idType = list[10] as String?
                val address = list[11] as String?
                val country = list[12] as String?
                val documentImageBase64 = list[13] as String?
                val fullData = list[14] as Map<String?, String?>?
                val fullName = list[15] as String?
                val idNumber = list[16] as String?
                val phoneNumber = list[17] as String?
                val phoneNumber2 = list[18] as String?
                val expirationDate = list[19] as String?
                val secondaryIdNumber = list[20] as String?
                val idNumberPreviouslyRegistered = list[21] as Boolean?
                val previousRegistrantsUserIds = list[22] as List<String?>?
                return FlutterEnhancedDocumentVerificationJobResult(
                    actions,
                    resultCode,
                    resultText,
                    resultType,
                    smileJobId,
                    partnerParams,
                    antifraud,
                    dob,
                    photoBase64,
                    gender,
                    idType,
                    address,
                    country,
                    documentImageBase64,
                    fullData,
                    fullName,
                    idNumber,
                    phoneNumber,
                    phoneNumber2,
                    expirationDate,
                    secondaryIdNumber,
                    idNumberPreviouslyRegistered,
                    previousRegistrantsUserIds,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                actions.toList(),
                resultCode,
                resultText,
                resultType,
                smileJobId,
                partnerParams.toList(),
                antifraud?.toList(),
                dob,
                photoBase64,
                gender,
                idType,
                address,
                country,
                documentImageBase64,
                fullData,
                fullName,
                idNumber,
                phoneNumber,
                phoneNumber2,
                expirationDate,
                secondaryIdNumber,
                idNumberPreviouslyRegistered,
                previousRegistrantsUserIds,
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterEnhancedDocumentVerificationJobStatusResponse(
        val timestamp: String,
        val jobComplete: Boolean,
        val jobSuccess: Boolean,
        val code: String,
        val result: FlutterEnhancedDocumentVerificationJobResult? = null,
        val resultString: String? = null,
        val history: List<FlutterEnhancedDocumentVerificationJobResult?>? = null,
        val imageLinks: FlutterImageLinks? = null,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterEnhancedDocumentVerificationJobStatusResponse {
                val timestamp = list[0] as String
                val jobComplete = list[1] as Boolean
                val jobSuccess = list[2] as Boolean
                val code = list[3] as String
                val result: FlutterEnhancedDocumentVerificationJobResult? =
                    (list[4] as List<Any?>?)?.let {
                        FlutterEnhancedDocumentVerificationJobResult.fromList(it)
                    }
                val resultString = list[5] as String?
                val history = list[6] as List<FlutterEnhancedDocumentVerificationJobResult?>?
                val imageLinks: FlutterImageLinks? =
                    (list[7] as List<Any?>?)?.let {
                        FlutterImageLinks.fromList(it)
                    }
                return FlutterEnhancedDocumentVerificationJobStatusResponse(
                    timestamp,
                    jobComplete,
                    jobSuccess,
                    code,
                    result,
                    resultString,
                    history,
                    imageLinks,
                )
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                timestamp,
                jobComplete,
                jobSuccess,
                code,
                result?.toList(),
                resultString,
                history,
                imageLinks?.toList(),
            )
    }
    
    /** Generated class from Pigeon that represents data sent in messages. */
    data class FlutterProductsConfigRequest(
        val partnerId: String,
        val timestamp: String,
        val signature: String,
    ) {
        companion object {
            @Suppress("UNCHECKED_CAST")
            fun fromList(list: List<Any?>): FlutterProductsConfigRequest {
                val partnerId = list[0] as String
                val timestamp = list[1] as String
                val signature = list[2] as String
                return FlutterProductsConfigRequest(partnerId, timestamp, signature)
            }
        }
    
        fun toList(): List<Any?> =
            listOf<Any?>(
                partnerId,
                timestamp,
                signature,
            )
    }
    
    /** Generated class fr...

    Comment on lines 85 to 100
    try {
    SmileID.moshi
    .newBuilder()
    .add(SelfieCaptureResultAdapter.FACTORY)
    .build()
    val json =
    try {
    moshi
    .adapter(SmartSelfieCaptureResult::class.java)
    .toJson(result)
    } catch (e: Exception) {
    onError(e)
    return@onFinished
    }
    json?.let { js ->
    onSuccessJson(js)
    .adapter(SmileIDCaptureResult.SmartSelfieCapture::class.java)
    .toJson(
    SmileIDCaptureResult.SmartSelfieCapture(
    selfieFile = res.data.selfieFile.absolutePath,
    livenessFiles =
    res.data.livenessFiles.map { file ->
    file.absolutePath
    },
    ),
    )
    } catch (e: Exception) {
    onError(e)
    return
    }
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Suggestion: Add null check for selfieFile to prevent NullPointerException when accessing absolutePath property. The selfieFile could potentially be null in some cases. [possible issue, importance: 8]

    Suggested change
    try {
    SmileID.moshi
    .newBuilder()
    .add(SelfieCaptureResultAdapter.FACTORY)
    .build()
    val json =
    try {
    moshi
    .adapter(SmartSelfieCaptureResult::class.java)
    .toJson(result)
    } catch (e: Exception) {
    onError(e)
    return@onFinished
    }
    json?.let { js ->
    onSuccessJson(js)
    .adapter(SmileIDCaptureResult.SmartSelfieCapture::class.java)
    .toJson(
    SmileIDCaptureResult.SmartSelfieCapture(
    selfieFile = res.data.selfieFile.absolutePath,
    livenessFiles =
    res.data.livenessFiles.map { file ->
    file.absolutePath
    },
    ),
    )
    } catch (e: Exception) {
    onError(e)
    return
    }
    val json =
    try {
    SmileID.moshi
    .adapter(SmileIDCaptureResult.SmartSelfieCapture::class.java)
    .toJson(
    SmileIDCaptureResult.SmartSelfieCapture(
    selfieFile = res.data.selfieFile?.absolutePath,
    livenessFiles =
    res.data.livenessFiles.map { file ->
    file.absolutePath
    },
    ),
    )
    } catch (e: Exception) {
    onError(e)
    return
    }

    @JNdhlovu JNdhlovu mentioned this pull request Mar 20, 2025

    @JsonClass(generateAdapter = true, generator = "sealed:type")
    sealed class SmileIDCaptureResult {
    abstract val selfieFile: String?
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Should we set the default value for all those parameters to null? (across the whole file)

    @@ -105,7 +104,12 @@ internal class SmileIDDocumentCaptureView private constructor(
    }
    DocumentCaptureScreen(
    jobId = jobId,
    side = if (isDocumentFrontSide) DocumentCaptureSide.Front else DocumentCaptureSide.Back,
    side =
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    The inline statement should be fine? Any reason to change that?

    .adapter(SmileIDCaptureResult.DocumentCaptureResult::class.java)
    .toJson(
    SmileIDCaptureResult.DocumentCaptureResult.DocumentCapture(
    documentFrontFile =
    Copy link
    Contributor

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    I'd keep the inline statements here as well - its less code and more readable to me?

    Copy link
    Contributor

    @robin-smileid robin-smileid left a comment

    Choose a reason for hiding this comment

    The reason will be displayed to describe this comment to others. Learn more.

    Left a few comments. Also can we please add a changelog entry now that this is a separate PR?

    @JNdhlovu
    Copy link
    Contributor Author

    JNdhlovu commented Apr 7, 2025

    @JNdhlovu JNdhlovu closed this Apr 7, 2025
    @jumaallan jumaallan deleted the feature/jsonresults branch June 16, 2025 19:07
    Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
    Projects
    None yet
    Development

    Successfully merging this pull request may close these issues.

    3 participants