Files
securebit-chat/node_modules/html5-qrcode/src/core.ts

354 lines
9.2 KiB
TypeScript
Raw Normal View History

/**
* @fileoverview
* Core libraries, interfaces, enums shared across {@class Html5Qrcode} & {@class Html5QrcodeScanner}
*
* @author mebjas <minhazav@gmail.com>
*
* The word "QR Code" is registered trademark of DENSO WAVE INCORPORATED
* http://www.denso-wave.com/qrcode/faqpatent-e.html
*/
/**
* Code formats supported by this library.
*/
export enum Html5QrcodeSupportedFormats {
QR_CODE = 0,
AZTEC,
CODABAR,
CODE_39,
CODE_93,
CODE_128,
DATA_MATRIX,
MAXICODE,
ITF,
EAN_13,
EAN_8,
PDF_417,
RSS_14,
RSS_EXPANDED,
UPC_A,
UPC_E,
UPC_EAN_EXTENSION,
}
/** {@code Html5QrcodeSupportedFormats} to friendly name map. */
const html5QrcodeSupportedFormatsTextMap
: Map<Html5QrcodeSupportedFormats, string> = new Map(
[
[ Html5QrcodeSupportedFormats.QR_CODE, "QR_CODE" ],
[ Html5QrcodeSupportedFormats.AZTEC, "AZTEC" ],
[ Html5QrcodeSupportedFormats.CODABAR, "CODABAR" ],
[ Html5QrcodeSupportedFormats.CODE_39, "CODE_39" ],
[ Html5QrcodeSupportedFormats.CODE_93, "CODE_93" ],
[ Html5QrcodeSupportedFormats.CODE_128, "CODE_128" ],
[ Html5QrcodeSupportedFormats.DATA_MATRIX, "DATA_MATRIX" ],
[ Html5QrcodeSupportedFormats.MAXICODE, "MAXICODE" ],
[ Html5QrcodeSupportedFormats.ITF, "ITF" ],
[ Html5QrcodeSupportedFormats.EAN_13, "EAN_13" ],
[ Html5QrcodeSupportedFormats.EAN_8, "EAN_8" ],
[ Html5QrcodeSupportedFormats.PDF_417, "PDF_417" ],
[ Html5QrcodeSupportedFormats.RSS_14, "RSS_14" ],
[ Html5QrcodeSupportedFormats.RSS_EXPANDED, "RSS_EXPANDED" ],
[ Html5QrcodeSupportedFormats.UPC_A, "UPC_A" ],
[ Html5QrcodeSupportedFormats.UPC_E, "UPC_E" ],
[ Html5QrcodeSupportedFormats.UPC_EAN_EXTENSION, "UPC_EAN_EXTENSION" ]
]
);
/**
* Indicates the type of decoded text.
*
* Note: this is very experimental in nature at the moment.
*/
export enum DecodedTextType {
UNKNOWN = 0,
URL,
}
/** Returns true if the passed object instance is a valid format. */
export function isValidHtml5QrcodeSupportedFormats(format: any): boolean {
return Object.values(Html5QrcodeSupportedFormats).includes(format);
}
/**
* Types of scans supported by the library
*/
export enum Html5QrcodeScanType {
SCAN_TYPE_CAMERA = 0, // Camera based scanner.
SCAN_TYPE_FILE = 1 // File based scanner.
}
/**
* Constants used in QR code library.
*/
export class Html5QrcodeConstants {
static GITHUB_PROJECT_URL: string
= "https://github.com/mebjas/html5-qrcode";
static SCAN_DEFAULT_FPS = 2;
static DEFAULT_DISABLE_FLIP = false;
static DEFAULT_REMEMBER_LAST_CAMERA_USED = true;
static DEFAULT_SUPPORTED_SCAN_TYPE = [
Html5QrcodeScanType.SCAN_TYPE_CAMERA,
Html5QrcodeScanType.SCAN_TYPE_FILE];
}
/** Defines dimension for QR Code Scanner. */
export interface QrDimensions {
width: number;
height: number;
}
/**
* A function that takes in the width and height of the video stream
* and returns QrDimensions.
*
* Viewfinder refers to the video showing camera stream.
*/
export type QrDimensionFunction =
(viewfinderWidth: number, viewfinderHeight: number) => QrDimensions;
/**
* Defines bounds of detected QR code w.r.t the scan region.
*/
export interface QrBounds extends QrDimensions {
x: number;
y: number;
}
/** Format of detected code. */
export class QrcodeResultFormat {
public readonly format: Html5QrcodeSupportedFormats;
public readonly formatName: string;
private constructor(
format: Html5QrcodeSupportedFormats,
formatName: string) {
this.format = format;
this.formatName = formatName;
}
public toString(): string {
return this.formatName;
}
public static create(format: Html5QrcodeSupportedFormats) {
if (!html5QrcodeSupportedFormatsTextMap.has(format)) {
throw `${format} not in html5QrcodeSupportedFormatsTextMap`;
}
return new QrcodeResultFormat(
format, html5QrcodeSupportedFormatsTextMap.get(format)!);
}
}
/** Data class for QR code result used for debugging. */
export interface QrcodeResultDebugData {
/** Name of the decoder that was used for decoding. */
decoderName?: string;
}
/**
* Detailed scan result.
*/
export interface QrcodeResult {
/** Decoded text. */
text: string;
/** Format that was successfully scanned. */
format?: QrcodeResultFormat,
/**
* The bounds of the decoded QR code or bar code in the whole stream of
* image.
*
* Note: this is experimental, and not fully supported.
*/
bounds?: QrBounds;
/**
* If the decoded text from the QR code or bar code is of a known type like
* url or upi id or email id.
*
* Note: this is experimental, and not fully supported.
*/
decodedTextType?: DecodedTextType;
/** Data class for QR code result used for debugging. */
debugData?: QrcodeResultDebugData;
}
/**
* QrCode result object.
*/
export interface Html5QrcodeResult {
decodedText: string;
result: QrcodeResult;
}
/**
* Static factory for creating {@interface Html5QrcodeResult} instance.
*/
export class Html5QrcodeResultFactory {
static createFromText(decodedText: string): Html5QrcodeResult {
let qrcodeResult = {
text: decodedText
};
return {
decodedText: decodedText,
result: qrcodeResult
};
}
static createFromQrcodeResult(qrcodeResult: QrcodeResult)
: Html5QrcodeResult {
return {
decodedText: qrcodeResult.text,
result: qrcodeResult
};
}
}
/**
* Different kind of errors that can lead to scanning error.
*/
export enum Html5QrcodeErrorTypes {
UNKWOWN_ERROR = 0,
IMPLEMENTATION_ERROR = 1,
NO_CODE_FOUND_ERROR = 2
}
/**
* Interface for scan error response.
*/
export interface Html5QrcodeError {
errorMessage: string;
type: Html5QrcodeErrorTypes;
}
/**
* Static factory for creating {@interface Html5QrcodeError} instance.
*/
export class Html5QrcodeErrorFactory {
static createFrom(error: any): Html5QrcodeError {
return {
errorMessage: error,
type: Html5QrcodeErrorTypes.UNKWOWN_ERROR
};
}
}
/**
* Type for a callback for a successful code scan.
*/
export type QrcodeSuccessCallback
= (decodedText: string, result: Html5QrcodeResult) => void;
/**
* Type for a callback for failure during code scan.
*/
export type QrcodeErrorCallback
= (errorMessage: string, error: Html5QrcodeError) => void;
/** Code decoder interface. */
export interface QrcodeDecoderAsync {
/**
* Decodes content of the canvas to find a valid QR code or bar code.
*
* @param canvas a valid html5 canvas element.
*/
decodeAsync(canvas: HTMLCanvasElement): Promise<QrcodeResult>;
}
/**
* Code robust decoder interface.
*
* <p> A robust decoder may sacrifice latency of scanning for scanning quality.
* Ideal for file scan kind of operation.
*/
export interface RobustQrcodeDecoderAsync extends QrcodeDecoderAsync {
/**
* Decodes content of the canvas to find a valid QR code or bar code.
*
* <p>The method implementation will run the decoder more robustly at the
* expense of latency.
*
* @param canvas a valid html5 canvas element.
*/
decodeRobustlyAsync(canvas: HTMLCanvasElement): Promise<QrcodeResult>;
}
/** Interface for logger. */
export interface Logger {
log(message: string): void;
warn(message: string): void;
logError(message: string, isExperimental?: boolean): void;
logErrors(errors: Array<any>): void;
}
/**
* Base logger implementation based on browser console.
*
* This can be replaced by a custom implementation of logger.
*
*/
export class BaseLoggger implements Logger {
private verbose: boolean;
public constructor(verbose: boolean) {
this.verbose = verbose;
}
public log(message: string): void {
if (this.verbose) {
// eslint-disable-next-line no-console
console.log(message);
}
}
public warn(message: string): void {
if (this.verbose) {
// eslint-disable-next-line no-console
console.warn(message);
}
}
public logError(message: string, isExperimental?: boolean)
: void {
if (this.verbose || isExperimental === true) {
// eslint-disable-next-line no-console
console.error(message);
}
}
public logErrors(errors: Array<any>): void {
if (errors.length === 0) {
throw "Logger#logError called without arguments";
}
if (this.verbose) {
// eslint-disable-next-line no-console
console.error(errors);
}
}
}
//#region global functions
/** Returns true if the {@param obj} is null or undefined. */
export function isNullOrUndefined(obj?: any) {
return (typeof obj === "undefined") || obj === null;
}
/** Clips the {@code value} between {@code minValue} and {@code maxValue}. */
export function clip(value: number, minValue: number, maxValue: number) {
if (value > maxValue) {
return maxValue;
}
if (value < minValue) {
return minValue;
}
return value;
}
//#endregion