import { DecodedCredential, VerifiableCredential, } from '../machines/VerifiableCredential/VCMetaMachine/vc'; import {__AppId} from './GlobalVariables'; import {MIMOTO_BASE_URL, REQUEST_TIMEOUT} from './constants'; export type HTTP_METHOD = 'GET' | 'POST' | 'PATCH' | 'PUT' | 'DELETE'; export class BackendResponseError extends Error { constructor(name: string, message: string) { super(message); this.name = name; } } export async function request( method: HTTP_METHOD, path: `/${string}` | string, body?: Record, host = MIMOTO_BASE_URL, headers: Record = { 'Content-Type': 'application/json', }, timeoutMillis?: undefined | number, ) { if (path.includes('residentmobileapp')) headers['X-AppId'] = __AppId.getValue(); let response; const requestUrl = path.indexOf('https://') != -1 ? path : host + path; if (timeoutMillis === undefined) { response = await fetch(requestUrl, { method, headers, body: body ? JSON.stringify(body) : undefined, }); } else { console.log(`making a web request to ${requestUrl}`); let controller = new AbortController(); setTimeout(() => { controller.abort(); }, timeoutMillis); try { response = await fetch(requestUrl, { method, headers, body: body ? JSON.stringify(body) : undefined, signal: controller.signal, }); } catch (error) { console.error( `Error occurred while making request: ${host + path}: ${error}`, ); if (error.name === 'AbortError') { throw new Error(REQUEST_TIMEOUT); } throw error; } } const jsonResponse = await response.json(); if (response.status >= 400) { let backendUrl = host + path; let errorMessage = jsonResponse.message || (typeof jsonResponse.error === 'object' ? JSON.stringify(jsonResponse.error) : jsonResponse.error); console.error( `The backend API ${backendUrl} returned error code ${response.status} with message --> ${errorMessage}`, ); throw new Error(errorMessage); } if (jsonResponse.errors && jsonResponse.errors.length) { let backendUrl = host + path; const {errorCode, errorMessage} = jsonResponse.errors.shift(); console.error( 'The backend API ' + backendUrl + ' returned error response --> error code is : ' + errorCode + ' error message is : ' + errorMessage, ); throw new BackendResponseError(errorCode, errorMessage); } return jsonResponse; } interface ResponseError { errorCode: string; errorMessage: string; } interface BackendResponse { id: string; version: string; response: T; str?: string; responsetime?: string; metadata?: string; errors?: ResponseError[]; } export type OtpRequestResponse = BackendResponse<{ maskedMobile?: string; maskedEmail?: string; }>; export type VcGenerateResponse = BackendResponse<{ vc: string; message: string; }>; export type CredentialRequestResponse = BackendResponse<{ id: string; requestId: string; }>; export type CredentialStatusResponse = BackendResponse<{ statusCode: 'NEW' | 'ISSUED' | 'printing'; }>; export interface CredentialDownloadResponse { credential?: DecodedCredential; verifiableCredential?: VerifiableCredential; }