/**
* @summary Default URL for API requests.
* @constant
* @type {string}
*/
export const DEFAULT_URL = 'https://local.capturebridge.net:9001'
function CaptureBridgeSetDefaultURL () {
// Prefer <meta name="capturebridge:url" content="proto://fqdn" /> if set
if (typeof document === 'object') {
const url = document.querySelector('meta[name="capturebridge:url"]')
if (url && url.content) {
return url.content
}
}
// Prefer CAPTURE_BRIDGE_URL if set on the global window object (Browser)
if (typeof window === 'object' && window?.CAPTURE_BRIDGE_URL) {
return window.CAPTURE_BRIDGE_URL
}
// Prefer CAPTURE_BRIDGE_URL if set on in the environment (Node.js)
if (typeof process === 'object' && process?.env?.CAPTURE_BRIDGE_URL) {
return process?.env?.CAPTURE_BRIDGE_URL
}
// Failing an explicit CAPTURE_BRIDGE_URL, use the URL in which the SDK
// is being served from (Browser)
if (typeof window === 'object' && window?.location?.origin) {
return window.location.origin
}
// If all else fails, use the default vanity URL
return DEFAULT_URL
}
/**
* @summary Base URL for all HTTP API requests.
*
* Due to the various environments in which the SDK can be loaded and the
* different ways that a Capture Bridge instance may be configured. The
* `BASE_URL` variable used for all default HTTP API request can be set in
* several ways:
*
* When running the SDK within a web browser the following locations are
* checked, in order:
* 1. A {@link https://developer.mozilla.org/en-US/docs/Web/HTML/Element/meta|meta} tag containing a url: `<meta name="capturebridge:url" content="proto://fqdn:port" />`
* 2. In the global {@link https://developer.mozilla.org/en-US/docs/Web/API/Window|Window} object: `window.CAPTURE_BRIDGE_URL`
* 3. In the {@link https://developer.mozilla.org/en-US/docs/Web/API/Location/origin|origin} in which the SDK is running: `window.location.origin`
* 4. The `DEFAULT_URL` constant from `Common.js`
*
* When running the SDK within Node.js the following locations are
* checked, in order:
* 1. In a `CAPTURE_BRIDGE_URL` {@link https://nodejs.org/api/process.html#processenv|environment variable}
* 2. The `DEFAULT_URL` constant from `Common.js`
*
* **Note** that each constructor also accepts a `baseUrl` parameter that will override
* any value for `BASE_URL` previously set.
*
* @constant
* @type {string}
* @default {@link https://local.capturebridge.net:9001}
*/
export const BASE_URL = CaptureBridgeSetDefaultURL()
/**
* Common {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API|Fetch}
* options for making
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/POST|POST}
* requests to the API.
* @constant
* @type {object}
*/
export const POST = {
mode: 'cors',
method: 'post'
}
/**
* @summary
* Common {@link https://developer.mozilla.org/en-US/docs/Web/API/Fetch_API|Fetch}
* options for making
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/DELETE|DELETE}
* requests to the API.
* @constant
* @type {object}
*/
export const DELETE = {
mode: 'cors',
method: 'delete'
}
/**
* @summary Default options for stream operations
* @constant
* @property {number?} rotate - Angle, in degrees to rotate the stream. Must be
* a value from -359 to 359. A value outside of that range, or a 0 will perform
* no rotation.
* @typedef {object} StreamOptions
*/
export const DEFAULT_STREAM_OPT = {
rotate: null
}
/**
* @typedef {string} CaptureResponseKind
* @summary Specifies the desired return type for a captured object. Valid
* values are `objecturl`, `blob`, `buffer`, `base64`, or `dataurl`.
*
* - `objecturl` will load the captured object into an
* {@link https://developer.mozilla.org/en-US/docs/Web/API/URL/createObjectURL_static|ObjectURL}
* that can be set directly on an img tag's src attribute. Note that these URLs
* should be {@link https://developer.mozilla.org/en-US/docs/Web/API/URL/revokeObjectURL_static|revoked}
* when they are no longer needed.
*
* - `buffer` will load the image into an
* {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/ArrayBuffer|ArrayBuffer}
*
* - `blob` will return a
* {@link https://developer.mozilla.org/en-US/docs/Web/API/Blob|Blob} that can
* be used with a
* {@link https://developer.mozilla.org/en-US/docs/Web/API/FileReader|FileReader}.
*
* - `base64` will return the image contents as a
* {@link https://en.wikipedia.org/wiki/Base64|Base64} encoded string that is
* suitable for use with JSON serialization.
*
* - `dataurl` will return a
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs|Data URL}
* that can be set on an img tag's src attribute or loaded as a document
* location.
*
*/
/**
* @typedef {string} CaptureResponseFormat
* @summary The image format to be returned.
*
* Valid values:
*
* - `jpg`
* - `tiff`
* - `gif`
* - `png`
*
* If not provided, a plugin or device-specific format will be returned.
*
* **Note:**
* - Some plugins have configuration options for specifying the return format,
* such configuration options should be used instead of this parameter to
* prevent unecessary transcoding.
* - Web browsers are not typically capable of displaying TIFF images.
*
*/
/**
* @summary Default options for capture operations.
* @constant
* @property {number?} rotate - Angle, in degrees to rotate the captured object.
* Must be a value from -359 to 359. A value of 0 will perform no rotation.
* @property {boolean?} base64 - Return the captured object as a base64 encoded
* string. The default behavior is to return the image as binary data.
* @property {CaptureResponseKind} kind - Specifies how to return the captured
* object. Some SDK methods that are designed to only return a particular type,
* such as {@link Device#frameAsBase64}, ignore this parameter. This parameter
* is also not sent in API requests, it is used internally by the SDK for
* constructing the appropriate response type.
* @property {CaptureResponseFormat} format - The image format to be returned.
*
* @typedef {object} CaptureOptions
*/
export const DEFAULT_CAPTURE_OPT = {
rotate: null,
base64: false,
format: null,
kind: 'objecturl'
}
/**
* @summary `data:` prefix for JPEG
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs|Data URLs}
* @constant
* @type {string}
*/
export const DATAURL_JPEG = 'data:image/jpeg;base64,'
/**
* @summary `data:` prefix for PNG
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs|Data URLs}
* @constant
* @type {string}
*/
export const DATAURL_PNG = 'data:image/png;base64,'
/**
* @summary `data:` prefix for GIF
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs|Data URLs}
* @constant
* @type {string}
*/
export const DATAURL_GIF = 'data:image/gif;base64,'
/**
* @summary `data:` prefix for JSON
* {@link https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/Data_URLs|Data URLs}
* @constant
* @type {string}
*/
export const DATAURL_JSON = 'data:application/json;base64,'
/**
* @summary For a given base64 string, convert it to the appropriate Data URL
* @constant
* @type {string}
*/
export const base64ToDataURL = base64 => {
const magicBytes = atob(base64.slice(0, 6))
const byteArray = new Uint8Array(magicBytes.length)
for (let i = 0; i < magicBytes.length; i++) {
byteArray[i] = magicBytes.charCodeAt(i)
}
// Check for JPEG magic number (FF D8 FF)
if (byteArray[0] === 0xFF && byteArray[1] === 0xD8 && byteArray[2] === 0xFF) {
return DATAURL_JPEG + base64
}
// Check for PNG magic number (89 50 4E 47)
if (byteArray[0] === 0x89 && byteArray[1] === 0x50 && byteArray[2] === 0x4E && byteArray[3] === 0x47) {
return DATAURL_PNG + base64
}
// Check for GIF magic number (47 49 46 38)
if (byteArray[0] === 0x47 && byteArray[1] === 0x49 && byteArray[2] === 0x46 && byteArray[3] === 0x38) {
return DATAURL_GIF + base64
}
throw new Error('Unknown image format provided in Base64 string')
}
/**
* @summary Strip the data URL identifier from a string
* @constant
* @type {string}
*/
export const stripDataUrl = dataUrl => {
const dataUrls = [DATAURL_JPEG, DATAURL_PNG, DATAURL_GIF, DATAURL_JSON]
for (const i in dataUrls) {
const prefix = dataUrls[i]
if (dataUrl.startsWith(prefix)) {
return dataUrl.replace(prefix, '')
}
}
throw new Error(`Data URL prefix must be one of: ${dataUrls.join(',')}`)
}
/**
* An Async/Await version of
* {@link https://developer.mozilla.org/en-US/docs/Web/API/setTimeout|setTimeout}
* @private
*/
export const timeout = millis => {
return new Promise(resolve => setTimeout(resolve, millis))
}
/**
* Convert a Blob to a Buffer
* @private
*/
export const blobToBuffer = blob => {
return new Promise(resolve => {
const reader = new window.FileReader()
reader.onload = event => resolve(event.target.result)
reader.readAsArrayBuffer(blob)
})
}
/**
* Convert a Blob to a Base64 String
* @private
*/
export const blobToBase64 = blob => {
return new Promise(resolve => {
const reader = new window.FileReader()
reader.onload = event => resolve(event.target.result.split(',')[1])
reader.readAsDataURL(blob)
})
}
/**
* Helper function to throw if an http response was a error.
* @private
*/
export const checkResponse = async (response) => {
if (!response.ok) {
const error = await response.json()
const msg = error.message || error.summary || error.code || 'Unexpected error'
const ex = new Error(msg)
ex.code = error.code || 500
ex.summary = error.summary || error.error || 'Unexpected error'
throw ex
}
}
/**
* Helper function to convert a key/value map to a string, removing any items
* that are null or undefined (instead of converting them to a string which
* URLSearchParams().toString() will do.)
* @private
*/
export const urlParamsToString = (params) => {
const filtered = {}
Object.keys(params).forEach(key => {
if (params[key] !== null && params[key] !== undefined) {
filtered[key] = params[key]
}
})
return new URLSearchParams(filtered).toString()
}
/**
* Allows passing in a string for the response type of capture methods
* @private
*/
export const DEPRECATION_01 = true
/**
* Allows passing in a boolean to clear the screen for display methods
* @private
*/
export const DEPRECATION_02 = true