import type { HttpClient } from '@services' import { capitalizeName } from '../helpers/capitalize' import { http } from '../http/client' import { type HttpClientType, omyHttp } from '../httpExternal/omyClient' export type ApiResponseType = { data: { api_request: { error: Record resources: string[] status: string status_code: number url: string } document: { id: string name: string n_pages: number is_rotation_applied: boolean inference: { started_at: string finished_at: string processing_time: number pages: [ { id: number orientation: { value: number } prediction: Record< | 'alternate_name' | 'authority' | 'birth_date' | 'birth_place' | 'card_access_number' | 'country' | 'document_number' | 'document_side' | 'document_type' | 'expiry_date' | 'gender' | 'given_names' | 'id_number' | 'issuance_date' | 'issue_date' | 'nationality' | 'surname', Record<'value', string> | Record<'value', string>[] > extras: Record }, ] prediction: Record extras: Record } } } } export type Prediction = ApiResponseType['data']['document']['inference']['pages']['0']['prediction'] export type PredictKey = keyof Prediction export type PredictKeys = Array export type PassportType = { birth_date: string | null birth_place: string | null country: string | null expiry_date: string | null gender: string | null given_names: string[] | null id_number: string | null issuance_date: string | null surname: string | null } export type IDCardType = { alternate_name: string | null authority: string | null birth_date: string | null birth_place: string | null card_access_number: string | null document_number: string | null document_side: string | null document_type: string | null expiry_date: string | null gender: string | null given_names: string[] | null issue_date: string | null nationality: string | null surname: string | null } export type PredictDocumentData = Type extends 'passport' ? PassportType : IDCardType export class DocVerifier { private headers = {} private http = {} as HttpClient private apiUrl = '' constructor( private provider: { apiUrl: string apiKey: string httpClientType: HttpClientType }, ) { this.headers = { headers: { Authorization: `Token ${this.provider.apiKey}` }, } this.apiUrl = this.provider.apiUrl this.http = this.setHttp(this.provider.httpClientType) } private setHttp(httpClientType: HttpClientType) { const api = { name: 'mindee', url: this.apiUrl } as const return httpClientType === 'axios' ? http({ api, unserialized: true }) : omyHttp({ api }) } private getPredictData( predicKeys: PredictKeys, element: Prediction, ): PredictDocumentData { return predicKeys.reduce( (acc: Record, curr: PredictKey) => { // Capitalize names returned by Mindee const isNameField = [ 'surname', 'given_names', 'alternate_name', ].includes(curr) if (Array.isArray(element[curr])) { const currArray = element[curr] as Record<'value', string>[] acc[curr] = currArray .filter((el) => el.value) .map((el) => (isNameField ? capitalizeName(el.value) : el.value)) } else { const currObj = element[curr] as Record<'value', string> if (currObj.value) { acc[curr] = isNameField ? capitalizeName(currObj.value) : currObj.value } } return acc }, {}, ) as PredictDocumentData } private dataFormatter( data: ApiResponseType['data']['document']['inference']['pages'], ) { return data.map((element) => { const predicKeys = Object.keys(element.prediction) as PredictKeys return this.getPredictData(predicKeys, element.prediction) }) } async verifyPassport(file: string) { const res = await this.http .post( 'v1/products/mindee/passport/v1/predict', { document: file }, this.headers, ) .then((res) => typeof res.data === 'object' ? res : ({ data: res } as unknown as ApiResponseType), ) const dataFormatted = this.dataFormatter<'passport'>( res.data.document.inference.pages, ) return { data: dataFormatted, error: res.data.api_request.error, status: res.data.api_request.status, code: res.data.api_request.status_code, } } async verifyIdentityCard(file: string) { const res = await this.http .post( 'v1/products/mindee/idcard_fr/v2/predict', { document: file }, this.headers, ) .then((res) => typeof res.data === 'object' ? res : ({ data: res } as unknown as ApiResponseType), ) const dataFormatted = this.dataFormatter<'IDCard'>( res.data.document.inference.pages, ) return { data: dataFormatted, error: res.data.api_request.error, status: res.data.api_request.status, code: res.data.api_request.status_code, } } }