UNPKG

@privateid/small-age-sdk-alpha

Version:
314 lines 13.4 kB
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