nwa-client
Version:
Native WebApp client library
334 lines • 13.3 kB
JavaScript
var _a;
function generateDeviceId() {
const deviceId = self.crypto.randomUUID();
localStorage.setItem('deviceId', deviceId);
return deviceId;
}
function hasMinVersion(version) {
const matchApp = /(\d+)\.(\d+)\.(\d+)\+(\d+) NWA/i.exec(navigator.userAgent);
const matchMin = /(\d+)\.(\d+)\.(\d+)/i.exec(version);
if (!matchApp || !matchMin) {
return false;
}
const [majorA, minorA, patchA] = matchApp.slice(1).map(Number);
const [majorB, minorB, patchB] = matchMin.slice(1).map(Number);
if (majorA !== majorB) {
return majorA > majorB;
}
if (minorA !== minorB) {
return minorA > minorB;
}
return patchA >= patchB;
}
function getMeta(name) {
const meta = document.querySelector('meta[name="' + name + '"]');
if (meta) {
return meta.getAttribute('content');
}
else {
return '#FFFFFFFF';
}
}
function getInfos() {
const nVer = navigator.appVersion;
const nAgt = navigator.userAgent;
let browserName = navigator.appName;
let fullVersion = '' + parseFloat(navigator.appVersion);
let majorVersion = parseInt(navigator.appVersion, 10);
let nameOffset, verOffset, ix;
// In Opera, the true version is after "Opera" or after "Version"
if ((verOffset = nAgt.indexOf('Opera')) !== -1) {
browserName = 'Opera';
fullVersion = nAgt.substring(verOffset + 6);
if ((verOffset = nAgt.indexOf('Version')) !== -1) {
fullVersion = nAgt.substring(verOffset + 8);
}
}
// In MSIE, the true version is after "MSIE" in userAgent
else if ((verOffset = nAgt.indexOf('MSIE')) !== -1) {
browserName = 'Microsoft Internet Explorer';
fullVersion = nAgt.substring(verOffset + 5);
}
// In Chrome, the true version is after "Chrome"
else if ((verOffset = nAgt.indexOf('Chrome')) !== -1) {
browserName = 'Chrome';
fullVersion = nAgt.substring(verOffset + 7);
}
// In Safari, the true version is after "Safari" or after "Version"
else if ((verOffset = nAgt.indexOf('Safari')) !== -1) {
browserName = 'Safari';
fullVersion = nAgt.substring(verOffset + 7);
if ((verOffset = nAgt.indexOf('Version')) !== -1) {
fullVersion = nAgt.substring(verOffset + 8);
}
}
// In Firefox, the true version is after "Firefox"
else if ((verOffset = nAgt.indexOf('Firefox')) !== -1) {
browserName = 'Firefox';
fullVersion = nAgt.substring(verOffset + 8);
}
// In most other browsers, "name/version" is at the end of userAgent
else if ((nameOffset = nAgt.lastIndexOf(' ') + 1) < (verOffset = nAgt.lastIndexOf('/'))) {
browserName = nAgt.substring(nameOffset, verOffset);
fullVersion = nAgt.substring(verOffset + 1);
if (browserName.toLowerCase() === browserName.toUpperCase()) {
browserName = navigator.appName;
}
}
// trim the fullVersion string at semicolon/space if present
if ((ix = fullVersion.indexOf(';')) !== -1) {
fullVersion = fullVersion.substring(0, ix);
}
if ((ix = fullVersion.indexOf(' ')) !== -1) {
fullVersion = fullVersion.substring(0, ix);
}
majorVersion = parseInt('' + fullVersion, 10);
if (isNaN(majorVersion)) {
fullVersion = '' + parseFloat(navigator.appVersion);
majorVersion = parseInt(navigator.appVersion, 10);
}
return {
browserName,
fullVersion,
majorVersion,
};
}
let App;
const isNativeWebApp = /NWA/i.test(navigator.userAgent);
const isUpToDate = hasMinVersion('2.6.0');
if (isNativeWebApp && isUpToDate && window.NwaHandler) {
const isAndroid = /android/i.test(navigator.userAgent);
let requestId = 0;
const handlers = [];
const requests = [];
App = new Proxy(window.NwaHandler, {
// eslint-disable-next-line @typescript-eslint/no-explicit-any
get(target, propKey) {
if (propKey === 'isWeb') {
return false;
}
if (propKey === 'mobile' || propKey === 'nwa') {
return true;
}
return (...args) => {
if (propKey === 'notify' || propKey === 'emit') {
const channel = args.shift();
if (channel in handlers) {
try {
let success = true;
for (const handler of handlers[channel]) {
success = success && handler(...args) !== false;
}
return success;
}
catch (e) {
return false;
}
}
else {
return false;
}
}
else if (propKey === 'resolve' || propKey === 'reject' || propKey === 'onSuccess' || propKey === 'onError') {
const request = requests[args[0]];
if (request) {
if (args.length > 1) {
return request[propKey](args[1]);
}
else {
return request[propKey]();
}
}
else {
// eslint-disable-next-line max-len, no-console
console.error('Unable to resolve request. (id=' + args[0] + ', now=' + Date.now() + ', data=' + JSON.stringify(args[1]) + ')');
}
}
else if (target[propKey] === undefined) {
if (propKey === 'on') {
if (!handlers[args[0]]) {
handlers[args[0]] = [];
}
handlers[args[0]].push(args[1]);
}
const id = 'req-' + (requestId++) + '-' + Date.now();
if (isAndroid) {
if (target.request) {
return new Promise((resolve, reject) => {
requests[id] = { resolve, reject };
target.request(propKey, id, JSON.stringify(args));
});
}
else {
return new Promise((resolve, reject) => {
requests[id] = { resolve, reject };
target.postMessage(propKey, id, JSON.stringify(args));
});
}
}
else {
return target.postMessage(JSON.stringify({ method: propKey, params: args })).then((result) => {
if (result && result.compatError) {
throw result.compatError;
}
else {
return result;
}
});
}
}
};
},
});
// Register callbacks
window.NwaHandler.resolve = App.resolve;
window.NwaHandler.reject = App.reject;
window.NwaHandler.notify = App.notify;
window.NwaHandler.emit = App.notify; // Compat, to remove
window.NwaHandler.onNotification = App.notify; // Compat, to remove
// Bypass native browser functionalities
if (isAndroid) {
window.print = () => App.print();
navigator.share = (data) => App.share(data);
navigator.clipboard.writeText = (data) => App.copy(data);
navigator.clipboard.readText = () => App.paste();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.setAppBadge = (data) => App.setAppBadge(data);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.clearAppBadge = () => App.clearAppBadge();
navigator.vibrate = (data) => App.vibrate(data);
window.open = (url, name) => App.openUrl(url, name);
if (!('permissions' in navigator)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.permissions = {};
}
navigator.permissions.query = App.hasPermission;
}
else {
const positionCallbacks = [];
window.print = () => App.print();
window.open = (url, name) => App.openUrl(url, name);
navigator.share = (data) => App.share(data);
navigator.clipboard.writeText = (data) => App.copy(data);
navigator.clipboard.readText = () => App.paste();
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.setAppBadge = (data) => App.setAppBadge(data);
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
navigator.clearAppBadge = () => App.clearAppBadge();
navigator.vibrate = (data) => App.vibrate(data);
App.on('position', location => {
if (positionCallbacks.length) {
positionCallbacks.forEach(obj => obj.callback(location));
}
else {
App.watchPosition(false);
}
});
navigator.geolocation.watchPosition = (callback, errorCallback, options) => {
const watchId = Math.floor(Math.random() * Number.MAX_SAFE_INTEGER);
if (!positionCallbacks.length) {
App.watchPosition(true, options).then(callback).catch(errorCallback);
}
positionCallbacks.push({
id: watchId,
callback,
});
return watchId;
};
navigator.geolocation.clearWatch = (watchId) => {
positionCallbacks.filter((cb, i, arr) => {
if (cb.id === watchId) {
arr.splice(i, 1);
return true;
}
else {
return false;
}
});
if (!positionCallbacks.length) {
App.watchPosition(false);
}
};
navigator.geolocation.getCurrentPosition = (callback, errorCallback, settings) => {
return App.getCurrentPosition(settings).then(callback).catch(errorCallback);
};
}
window.select = function (params) {
return App.select(params).then((files) => {
const dataTransfer = new DataTransfer();
for (const file of files) {
const bytes = atob(file.data);
let length = bytes.length;
const out = new Uint8Array(length);
// Loop and convert.
while (length--) {
out[length] = bytes.charCodeAt(length);
}
dataTransfer.items.add(new File([out], file.name, { type: file.type }));
}
return dataTransfer;
});
};
document.addEventListener('DOMContentLoaded', () => {
try {
const viewport = getMeta('viewport');
const keyboardResize = !!viewport && viewport.includes('interactive-widget=resizes-content');
const appBarOffset = !!viewport && !viewport.includes('viewport-fit=cover');
const navBarOffset = !!viewport && !viewport.includes('viewport-fit=cover');
const backgroundColor = parseInt(getMeta('theme-color').substring(1), 16);
const appBarColor = parseInt(getMeta('app-bar-color').substring(1), 16);
const navBarColor = parseInt(getMeta('nav-bar-color').substring(1), 16);
App.updateAppStyle({
backgroundColor,
appBarColor,
navBarColor,
appBarOffset,
navBarOffset,
keyboardResize,
});
}
catch (e) {
console.error('Unable to update app style', e);
}
}, false);
App.getDeviceId().then((deviceId) => localStorage.setItem('deviceId', deviceId));
}
else {
if (isNativeWebApp) {
if (!isUpToDate) {
console.error('Deprecated NWA version');
}
if (!window.NwaHandler) {
console.error('NwaHandler not registered');
}
}
const deviceId = (_a = localStorage.getItem('deviceId')) !== null && _a !== void 0 ? _a : generateDeviceId();
App = {
isWeb: true,
mobile: false,
nwa: false,
getDeviceInfos: async () => {
const infos = getInfos();
return {
id: deviceId,
os: 'browser',
version: infos.fullVersion,
model: infos.browserName,
name: infos.browserName,
appVersion: null,
registrationToken: null,
};
},
getDeviceId: async () => deviceId,
on: async (event, handler) => {
//
},
};
}
export default App;
//# sourceMappingURL=index.js.map