SymphonyElectron/src/common/utils.ts
Kiran Niranjan 13e82bac00 Merge TS context isolation branch onto Typescript master branch (#598)
* Typescript 🎉

* Typescript 🎉 (logger, get-guid, string-format and throttle)

* Refactor typescript code

* consolidate all the utility functions to one file

* refactor protocol handler feature

* Typescript:

Add code documentation
Add pre-commit hooks

* Typescript: Fix logger formatting

* Typescript: Add support for react

* Typescript: Completed about app

* Typescript: Completed about app

* Typescript: Completed about app

* Typescript - Fix issues with about-app and add login to convert less to css

* Typescript - Fix loading screen

* Typescript - Add custom title bar

* Typescript - Add method to get locale

* Typescript - Add logic to clean up old logs

* Typescript - Add set badge count api

* Typescript - Complete application menu

* Typescript - Add logic to translate menu items

* Typescript - freeze window.ssf api

* Typescript - Handle popup menu on alt key press

* Typescript - Completed activity detection

* Typescript - Completed screen snippet

* Typescript - Add login to close screen snippet

* Typescript - Completed window actions & snackbar, Updated i18n module

* Typescript - Completed native crypto implementation & fixed bugs

* Typescript - Completed Desktop capturer & screen picker implementation

* Typescript - Optimize window actions

* Typescript - Add support for child window

* Typescript - fix pop url validation issue & browserify preload

* Typescript - Completed context menu implementation and fixed screen snippet

* Typescript - Completed screen sharing indicator and fixed i18n usage issue

* Typescript - Fix i18n locale setting issue

* Typescript - Completed download manager

* Typescript - Completed Basic auth

* Typescript - Network connectivity dialog

* Typescript - Handle certificate error

* Typescript - Add translation for certificate error dialog buttons

* Typescript - Add gulp tasks to compile less, typescript and copy files

* Typescript - Fix some issues with custom title bar, loading screen & screen snippet

* Typescript - Remove ES2015 lib

* :typescript: - Do not inject custom title bar for mac

* :typescript: - Fix screen sharing indicator text and format string

* Typescript - Fix esc to full screen

* Typescript - handle multiple/single instance of the client and add safety checks

* Typescript - Refactor code base

* Typescript - Optimize window validation and fix screen picker issue

* Typescript - Optimize protocol handler

* typescript: logger unit test

* typescript: activityDetection unit test (#560)

* ELECTRON-1022 - Create app bridge that communicates between renderer and preload via postMessage

* ELECTRON-1024 - Add support for screen share and screen sharing indicator

* config unit test (#566)

* ELECTRON-1024 - Fix screen sharing indicator close issue

* ELECTRON-1022 - Bump Symphony version to 5.0.0 (1.55)

* fixing jest coverage output report (#575)

* protocol handle unit test (#576)

* Typescript - Remove unwanted checks in protocol handler and add test cases

* added more tests to increase coverage to 100 for protocol handler

* Typescript download manager unit test (#579)

* adding enzyme

* download manager unit test

* Typescript - Completed notification workflow

* about app unit test

* Typescript - Fix notification styles

* fixing Compiler error: Generic type ReactElement<P, T> (#583)

* fix app path on windows (#580)

* basic auth unit test (#582)

* screen picker unit test (#587)

* screen picker unit test

* screen sharing indicator unit test

* loading screen unit test (#588)

* improving snapshot using snapshotSerializers to remove unnecessary things (#596)

* Typescript - Enforce braces for if/for/do/while statements.

* Typescript - Fix Lint issues and Unit test

* Typescript - Enable eofline (Ensure the file ends with a newline.)

* Typescript - Update logger logic and format

* Typescript - Provide option for user to set custom log path

* Typescript - Fix eofline in css files

* Typescript - ignore spec from compiling and remove unwanted rebuild command
2019-04-02 10:58:09 +05:30

211 lines
5.6 KiB
TypeScript

// regex match the semver (semantic version) this checks for the pattern X.Y.Z
// ex-valid v1.2.0, 1.2.0, 2.3.4-r51
const semver = /^v?(?:\d+)(\.(?:[x*]|\d+)(\.(?:[x*]|\d+)(?:-[\da-z-]+(?:\.[\da-z-]+)*)?(?:\+[\da-z-]+(?:\.[\da-z-]+)*)?)?)?$/i;
const patch = /-([0-9A-Za-z-.]+)/;
/**
* Splits the versions
* into major, minor and patch
* @param v
* @returns {String[]}
*/
const split = (v: string): string[] => {
const temp = v.replace(/^v/, '').split('.');
const arr = temp.splice(0, 2);
arr.push(temp.join('.'));
return arr;
};
/**
* This function tries to parse the version string
* @param v Version string
*/
const tryParse = (v: string): string | number => {
return Number.isNaN(Number(v)) ? v : Number(v);
};
/**
* Validates the version
* with the semver regex and returns
* -1 if not valid else 1
* @param version
* @returns {number}
*/
const validate = (version: string): number => {
if (!semver.test(version)) {
return -1;
}
return 1;
};
/**
* Compares the v1 version with the v2 version
* for all major, minor, patch
* if v1 > v2 returns 1
* if v1 < v2 returns -1
* if v1 = v2 returns 0
* @param v1
* @param v2
* @returns {number}
*/
export const compareVersions = (v1: string, v2: string): number => {
if (validate(v1) === -1 || validate(v2) === -1) {
return -1;
}
const s1 = split(v1);
const s2 = split(v2);
for (let i = 0; i < 3; i++) {
const n1 = parseInt(s1[i] || '0', 10);
const n2 = parseInt(s2[i] || '0', 10);
if (n1 > n2) {
return 1;
}
if (n2 > n1) {
return -1;
}
}
if ([s1[2], s2[2]].every(patch.test.bind(patch))) {
// @ts-ignore
const p1 = patch.exec(s1[2])[1].split('.').map(tryParse);
// @ts-ignore
const p2 = patch.exec(s2[2])[1].split('.').map(tryParse);
for (let k = 0; k < Math.max(p1.length, p2.length); k++) {
if (p1[k] === undefined || typeof p2[k] === 'string' && typeof p1[k] === 'number') {
return -1;
}
if (p2[k] === undefined || typeof p1[k] === 'string' && typeof p2[k] === 'number') {
return 1;
}
if (p1[k] > p2[k]) {
return 1;
}
if (p2[k] > p1[k]) {
return -1;
}
}
} else if ([s1[2], s2[2]].some(patch.test.bind(patch))) {
return patch.test(s1[2]) ? -1 : 1;
}
return 0;
};
/**
* Search given argv for argName using exact match or starts with. Comparison is case insensitive
* @param {Array} argv Array of strings
* @param {String} argName Arg name to search for.
* @param {Boolean} exactMatch If true then look for exact match otherwise
* try finding arg that starts with argName.
* @return {String} If found, returns the arg, otherwise null.
*/
export const getCommandLineArgs = (argv: string[], argName: string, exactMatch: boolean): string | null => {
if (!Array.isArray(argv)) {
throw new Error(`get-command-line-args: TypeError invalid func arg, must be an array: ${argv}`);
}
const argNameToFind = argName.toLocaleLowerCase();
for (let i = 0, len = argv.length; i < len; i++) {
const arg = argv[i].toLocaleLowerCase();
if ((exactMatch && arg === argNameToFind) ||
(!exactMatch && arg.startsWith(argNameToFind))) {
return argv[i];
}
}
return null;
};
/**
* Generates a guid,
* http://stackoverflow.com/questions/105034/create-guid-uuid-in-javascript
*
* @return {String} guid value in string
*/
export const getGuid = (): string => {
return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g,
(c) => {
const r = Math.random() * 16 | 0; // tslint:disable-line:no-bitwise
const v = c === 'x' ? r : (r & 0x3 | 0x8); // tslint:disable-line:no-bitwise
return v.toString(16);
});
};
/**
* Picks a filtered list of values
* in a given object based on fields
* @param object Object to be filtered
* @param fields Fields to be picked
*/
export const pick = (object: object, fields: string[]) => {
const obj = {};
for (const field of fields) {
if (object[field]) {
obj[field] = object[field];
}
}
return obj;
};
/**
* Limits your function to be called at most every milliseconds
*
* @param func
* @param wait
* @example const throttled = throttle(anyFunc, 500);
*/
export const throttle = (func: (...args) => void, wait: number): (...args) => void => {
if (wait <= 0) {
throw Error('throttle: invalid throttleTime arg, must be a number: ' + wait);
}
let isCalled: boolean = false;
return (...args) => {
if (!isCalled) {
func(...args);
isCalled = true;
setTimeout(() => isCalled = false, wait);
}
};
};
/**
* Formats a string with dynamic values
* @param str {String} String to be formatted
* @param data {Object} - Data to be added
*
* @example
* StringFormat(this will log {time}`, { time: '1234' })
*
* result:
* this will log 1234
*
* @return {*}
*/
export const formatString = (str: string, data?: object): string => {
if (!str || !data) {
return str;
}
for (const key in data) {
if (Object.prototype.hasOwnProperty.call(data, key)) {
return str.replace(/({([^}]+)})/g, (i) => {
const replacedKey = i.replace(/{/, '').replace(/}/, '');
if (!data[key] || !data[key][replacedKey]) {
return i;
}
return data[key][replacedKey];
});
}
}
return str;
};