ICAO.js

import Plugin from './Plugin.js'
import { BASE_URL, checkResponse } from './Common.js'

/**
 * ICAO
 * @classdesc Class for invoking ICAO checks on an image
 * @extends Plugin
 * @see {@link IFace}
 */
class ICAO extends Plugin {
  /**
   * Instantiate an ICAO plugin
   * @constructor
   * @param {string} [baseURL] - Protocol, domain, and port for the service.
   * @param {string|object} plugin - The ID of the desired plugin to use for
   * this instance or an existing Plugin object. The plugin must support the
   * `icao` method. Defaults to the `capture_verify_iface` plugin.
   *
   * @example
   * const icao = new ICAO()
   */
  constructor (plugin = 'capture_verify_iface', baseUrl = BASE_URL) {
    super(plugin, baseUrl)
  }

  /**
   * Check the ICAO compliance of an image
   * @param {string|ImageSource} image - A string containing base64 encoded image
   * data or an ImageSource object.
   *
   * @param {string|bool} [crop] - If falsy image will not be cropped, otherwise
   * the value will be interpreted as the preferred crop method which will vary
   * by plugin implementation.
   *
   * @param {string} [background=#ffffff] - Hexadecimal color that will fill in
   * any part of the cropped image that falls outside the original source image.
   *
   * @param {number} [cropEnlargement] - If either `full_frontal_extended` or
   * `token_frontal_extended` are supplied for the `crop` argument, this value
   * defines the amount of background image area enlargement.
   *
   * @returns {object} Results of the ICAO check, this may vary by plugin
   * implementation.
   *
   * @async
   * @example
   * // Take a photo with a Canon Camera and perform ICAO checks on the
   * // returned image
   * const camera = new CanonCamera()
   * const photo = await camera.takePhoto('base64')
   * const icao = new ICAO()
   * const results = await icao.check(photo)
   * const img = document.createElement('img')
   * img.src = 'data:image/jpeg;base64,' + results.cropped
   * console.log(`found ${result.faces_found} faces in the image`)
   * document.body.appendChild(img)
   */
  async check (image, cropMethod = false, cropBackground, cropEnlargement) {
    let imageData

    // If this is an ImageSource object fetch it's image data
    if (typeof image === 'object' && typeof image.data === 'function') {
      imageData = await image.data()
    } else if (typeof image === 'string') {
      imageData = image
    } else {
      throw new Error('Unexpected value provided for image parameter')
    }

    if (cropMethod === true) {
      cropMethod = 'token_frontal'
    }

    const body = {
      base64: imageData,
      crop: Boolean(cropMethod),
      crop_method: cropMethod || undefined,
      crop_background: cropBackground || undefined,
      crop_enlargement: cropEnlargement
    }
    const options = {
      method: 'POST',
      mode: 'cors',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify(body)
    }
    const url = `${this.baseUrl}/plugin/${this.id}/icao`
    const response = await fetch(url, options)
    await checkResponse(response)
    return await response.json()
  }
}

export default ICAO