@privateid/small-age-sdk-alpha
Version:
314 lines • 13.7 kB
JavaScript
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
import UAParser from 'ua-parser-js';
import { FacingMode } from './types';
import { PORTRAIT } from './constants';
import { getScreenOrientation } from './utils';
const cameraLowResHeight = 480;
const cameraLowResWidth = 1920;
const mobileCameraResWidth = 1200;
const mobileCameraResHeight = 1440;
export function getUserAgent() {
const userAgent = typeof window !== 'undefined' && navigator && window.navigator.userAgent;
return userAgent || undefined;
}
export function parseUserAgent() {
// This maybe evaluated in next.js Node rather than in Browser
if (!getUserAgent()) {
return undefined;
}
const parser = new UAParser();
return parser.getResult();
}
export function isPortrait() {
return getScreenOrientation() === PORTRAIT;
}
export function isBackCameraAndPortrait(faceMode) {
return isPortrait();
}
export function isMobileUA() {
const result = parseUserAgent();
if (!result || !result.device || !result.device.type) {
return false;
}
return ['mobile', 'tablet'].includes(result.device.type);
}
export function isFirefoxUA() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.browser) === null || _a === void 0 ? void 0 : _a.name) === 'Firefox';
}
export function isSafariUA() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.browser) === null || _a === void 0 ? void 0 : _a.name) === 'Safari';
}
export function isChromeUA() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.browser) === null || _a === void 0 ? void 0 : _a.name) === 'Chrome';
}
export function isSamsungUA() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.device) === null || _a === void 0 ? void 0 : _a.vendor) === 'Samsung';
}
export function isAndroid() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.name) === 'Android';
}
/**
* See https://developer.chrome.com/docs/multidevice/user-agent/#webview_user_agent
* This onloy detects the WebView after Android 4.4. It'd return false for older
* Android version.
*/
export function isAndroidWebView() {
var _a, _b;
const result = parseUserAgent();
// If the user-agent string contains "wv", 'ua-parser-js' will return the
// string "WebView" as part of its browser name.
return ((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.name) === 'Android' && /WebView/.test(String((_b = result === null || result === void 0 ? void 0 : result.browser) === null || _b === void 0 ? void 0 : _b.name));
}
export function isAndroid12OrAbove() {
return getMajorAndroidVersion() >= 12;
}
export function isIOSUA() {
var _a;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.name) === 'iOS';
}
export function getMajorAndroidVersion() {
var _a, _b;
const result = parseUserAgent();
const matched = ((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.name) === 'Android' ? String(((_b = result === null || result === void 0 ? void 0 : result.os) === null || _b === void 0 ? void 0 : _b.version) || '').match(/^\d+/) : null;
return matched ? parseInt(matched[0], 10) : NaN;
}
export function getMajorSafariVersion() {
var _a, _b;
const result = parseUserAgent();
const name = (_a = result === null || result === void 0 ? void 0 : result.browser) === null || _a === void 0 ? void 0 : _a.name;
if (name === 'Safari' || name === 'Mobile Safari') {
return parseInt(((_b = result === null || result === void 0 ? void 0 : result.browser) === null || _b === void 0 ? void 0 : _b.version) || '', 10);
}
return NaN;
}
export function getMajorChromeVersion() {
var _a, _b;
const result = parseUserAgent();
return ((_a = result === null || result === void 0 ? void 0 : result.browser) === null || _a === void 0 ? void 0 : _a.name.includes('Chrome')) ? parseInt(((_b = result === null || result === void 0 ? void 0 : result.browser) === null || _b === void 0 ? void 0 : _b.version) || '', 10) : NaN;
}
export function getMajorIOSVersion() {
var _a, _b;
const result = parseUserAgent();
const matched = ((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.name) === 'iOS' ? String(((_b = result === null || result === void 0 ? void 0 : result.os) === null || _b === void 0 ? void 0 : _b.version) || '').match(/^\d+/) : null;
return matched ? parseInt(matched[0], 10) : NaN;
}
export function getMajorMinorOsVersion() {
var _a;
const result = parseUserAgent();
const version = String(((_a = result === null || result === void 0 ? void 0 : result.os) === null || _a === void 0 ? void 0 : _a.version) || '');
const matched = version.match(/(^\d+)(\.\d+)?/);
return (matched && matched[0]) || 'unknown';
}
export function isWindows() {
var _a, _b;
return getPlatform() === 'desktop' && ((_b = (_a = parseUserAgent()) === null || _a === void 0 ? void 0 : _a.os) === null || _b === void 0 ? void 0 : _b.name) === 'Windows';
}
export function isMac() {
var _a, _b;
return getPlatform() === 'desktop' && ((_b = (_a = parseUserAgent()) === null || _a === void 0 ? void 0 : _a.os) === null || _b === void 0 ? void 0 : _b.name) === 'Mac OS';
}
export function isLinux() {
var _a;
const ua = parseUserAgent();
return ((_a = ua === null || ua === void 0 ? void 0 : ua.os) === null || _a === void 0 ? void 0 : _a.name) === 'Linux';
}
// This returns the "platform"- iphone vs android vs desktop used for reporting metrics.
// Do not make this into something with high cardinality- that will impact SignalFX.
// If you need to alter/add to these values, please make sure to update the relevant
// SignalFX metrics as well.
export function getPlatform() {
if (isAndroid()) {
return 'android';
}
if (isIOSUA()) {
return 'iphone';
}
return 'desktop';
}
export function isMobileDevice() {
return isMobileUA() || isAndroidDesktop() || isIOSDesktop();
}
// Whether it's an IOS browser requesting desktop site.
export function isIOSDesktop() {
// IOS browser => Request Desktop Site.
return isMac() && window.navigator.maxTouchPoints > 1;
}
export function isIOS() {
return isIOSUA() || isIOSDesktop();
}
export function isIOS15OrGreater() {
if (isIOSDesktop()) {
// In the past, the version of Safari has been in sync with the version of
// iOS. Therefore, we could use Safari's version as a proxy to determine
// the version of iOS. However, it's not possible to determine the iOS
// version using other types of browsers.
return getMajorSafariVersion() >= 15;
}
// iOS Mobile.
return getMajorIOSVersion() >= 15;
}
// Whether it's an Android browser requesting desktop site.
export function isAndroidDesktop() {
// Android browser => Request Desktop Site.
return isLinux() && window.navigator.maxTouchPoints > 1;
}
const BACK_CAMERA_WORDS = [
'rear',
'back',
'rück',
'arrière',
'trasera',
'trás',
'traseira',
'posteriore',
'后面',
'後面',
'背面',
'后置',
'後置',
'背置',
'задней',
'الخلفية',
'후',
'arka',
'achterzijde',
'หลัง',
'baksidan',
'bagside',
'sau',
'bak',
'tylny',
'takakamera',
'belakang',
'אחורית',
'πίσω',
'spate',
'hátsó',
'zadní',
'darrere',
'zadná',
'задня',
'stražnja',
'belakang',
'बैक',
];
const isBackCameraLabel = (label) => {
const lowerCase = (label === null || label === void 0 ? void 0 : label.toLowerCase()) || '';
return BACK_CAMERA_WORDS.some((keyword) => lowerCase === null || lowerCase === void 0 ? void 0 : lowerCase.includes(keyword));
};
export const isMobileBackCameraPortrait = ({ label, facingMode }) => {
const isBackCamera = isBackCameraLabel(label) || (facingMode === null || facingMode === void 0 ? void 0 : facingMode.includes(FacingMode.environment));
return isMobileDevice() && isBackCamera && isPortrait();
};
export const isFaceTimeCamera = (label, isDocumentScan) => isMac() && label.includes('FaceTime') && isDocumentScan;
export const getCameraList = (backOnly) => __awaiter(void 0, void 0, void 0, function* () {
try {
if (!navigator.mediaDevices) {
return [];
}
let cameraList = yield navigator.mediaDevices.enumerateDevices().then((devices) => {
const filteredDevices = devices.filter((device) => {
let filteredLabels = true;
if (!backOnly) {
filteredLabels = !isBackCameraLabel(device.label);
}
return device.kind === 'videoinput' && filteredLabels;
});
return filteredDevices.map((device) => {
// @ts-ignore
if (device === null || device === void 0 ? void 0 : device.getCapabilities) {
// @ts-ignore
return Object.assign(Object.assign({}, device === null || device === void 0 ? void 0 : device.getCapabilities()), { deviceId: device.deviceId, label: device.label });
}
return { deviceId: device.deviceId, label: device.label };
});
});
if (isAndroid()) {
cameraList = cameraList.sort((a, b) => (a.label < b.label ? -1 : 1));
}
return cameraList;
}
catch (error) {
// handleException(error, 'error listing cameras');
return [];
}
});
export const getVideoConstraints = (availableDevices, faceMode, requireHD, isDocumentScan, canvasResolution, hasError = false) => {
// Use 1.5 ratio. US DL are 1.58, passport are 1.42, so take something in the middle
let deviceId = availableDevices[0];
if (isIOS() && isDocumentScan && (availableDevices === null || availableDevices === void 0 ? void 0 : availableDevices.length) > 2) {
const ultraWideDevice = availableDevices.find(({ label }) => label.includes('Dual Wide') || label.includes('Back Triple'));
deviceId = ultraWideDevice || availableDevices[0];
}
let resizeMode = 'crop-and-scale';
if (isMobileDevice()) {
// Known cases that 'crop-and-scale' does not work.
if (
// Chrome 107+ on Android shows broken video in 'crop-and-scale'.
(isAndroid() && getMajorChromeVersion() >= 107) ||
// Samsung video driver has a bug when using resizeMode
(isSamsungUA() && !isAndroid12OrAbove())) {
resizeMode = 'none';
}
let videoWidth;
let videoHeight;
let aspectRatio;
if ((canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.width) && (canvasResolution === null || canvasResolution === void 0 ? void 0 : canvasResolution.height)) {
videoWidth = canvasResolution.width;
videoHeight = canvasResolution.height;
aspectRatio = 1.7777777778;
}
else {
videoWidth = isBackCameraAndPortrait(faceMode)
? // ? { min: cameraLowResHeight, max: mobileCameraResHeight }
{ ideal: mobileCameraResHeight }
: { ideal: cameraLowResWidth };
videoHeight = isBackCameraAndPortrait(faceMode)
? // ? { min: cameraLowResHeight, max: mobileCameraResHeight }
{ ideal: mobileCameraResHeight }
: undefined;
aspectRatio = isBackCameraAndPortrait(faceMode) ? 1 : 1.7777777778;
}
return {
audio: false,
video: {
facingMode: faceMode,
resizeMode,
width: videoWidth,
height: videoHeight,
deviceId: deviceId ? deviceId.deviceId : undefined,
aspectRatio,
focusMode: 'continuous',
},
};
}
return {
audio: false,
video: {
aspectRatio: 1.5,
// deviceId: deviceId ? deviceId.deviceId : undefined,
height: { min: cameraLowResHeight },
resizeMode,
},
};
};
//# sourceMappingURL=cameraUtils.js.map