From 9c138ddf25b24705b5f8068cd13f0ee672297412 Mon Sep 17 00:00:00 2001 From: Kiran Niranjan Date: Wed, 16 Jan 2019 23:30:59 +0530 Subject: [PATCH] Typescript - Refactor code base --- package.json | 4 +- src/{browser => app}/activity-detection.ts | 0 src/{browser => app}/app-cache-handler.ts | 0 src/{browser => app}/app-menu.ts | 2 +- .../auto-launch-controller.ts | 0 .../child-window-handler.ts} | 0 src/{browser => app}/chrome-flags.ts | 0 src/{browser => app}/config-handler.ts | 0 .../crypto-handler.ts} | 2 +- src/{browser => app}/dialog-handler.ts | 0 src/{browser => app}/main-api-handler.ts | 0 src/{browser => app}/main.ts | 2 +- src/{browser => app}/protocol-handler.ts | 0 .../reports.ts => app/reports-handler.ts} | 62 +++++++++++- .../screen-snippet-handler.ts | 0 .../spell-check-handler.ts} | 0 src/{browser => app}/window-actions.ts | 2 +- src/{browser => app}/window-handler.ts | 2 +- src/{browser => app}/window-utils.ts | 0 src/common/format-string.ts | 30 ------ src/common/i18n-preload.ts | 2 +- src/common/i18n.ts | 2 +- src/common/throttle.ts | 22 ----- src/common/utils.ts | 98 ++++++++++--------- src/renderer/ssf-api.ts | 10 +- 25 files changed, 125 insertions(+), 115 deletions(-) rename src/{browser => app}/activity-detection.ts (100%) rename src/{browser => app}/app-cache-handler.ts (100%) rename src/{browser => app}/app-menu.ts (99%) rename src/{browser => app}/auto-launch-controller.ts (100%) rename src/{browser/pop-out-window-handler.ts => app/child-window-handler.ts} (100%) rename src/{browser => app}/chrome-flags.ts (100%) rename src/{browser => app}/config-handler.ts (100%) rename src/{browser/crypto-library-handler.ts => app/crypto-handler.ts} (98%) rename src/{browser => app}/dialog-handler.ts (100%) rename src/{browser => app}/main-api-handler.ts (100%) rename src/{browser => app}/main.ts (98%) rename src/{browser => app}/protocol-handler.ts (100%) rename src/{browser/reports.ts => app/reports-handler.ts} (62%) rename src/{browser => app}/screen-snippet-handler.ts (100%) rename src/{browser/spell-checker-handler.ts => app/spell-check-handler.ts} (100%) rename src/{browser => app}/window-actions.ts (99%) rename src/{browser => app}/window-handler.ts (99%) rename src/{browser => app}/window-utils.ts (100%) diff --git a/package.json b/package.json index 27e840a6..0ab68791 100644 --- a/package.json +++ b/package.json @@ -6,8 +6,8 @@ "buildNumber": "0", "description": "Symphony desktop app (Foundation ODP)", "author": "Symphony", - "main": "lib/src/browser/main.js", - "types": "lib/src/browser/main.d.ts", + "main": "lib/src/app/main.js", + "types": "lib/src/app/main.d.ts", "scripts": { "compile": "npm run lint && gulp build", "lint": "tslint --project tsconfig.json", diff --git a/src/browser/activity-detection.ts b/src/app/activity-detection.ts similarity index 100% rename from src/browser/activity-detection.ts rename to src/app/activity-detection.ts diff --git a/src/browser/app-cache-handler.ts b/src/app/app-cache-handler.ts similarity index 100% rename from src/browser/app-cache-handler.ts rename to src/app/app-cache-handler.ts diff --git a/src/browser/app-menu.ts b/src/app/app-menu.ts similarity index 99% rename from src/browser/app-menu.ts rename to src/app/app-menu.ts index e1942367..a6a257c4 100644 --- a/src/browser/app-menu.ts +++ b/src/app/app-menu.ts @@ -5,7 +5,7 @@ import { i18n, LocaleType } from '../common/i18n'; import { logger } from '../common/logger'; import { autoLaunchInstance as autoLaunch } from './auto-launch-controller'; import { config, IConfig } from './config-handler'; -import { exportCrashDumps, exportLogs } from './reports'; +import { exportCrashDumps, exportLogs } from './reports-handler'; import { updateAlwaysOnTop } from './window-actions'; import { windowHandler } from './window-handler'; diff --git a/src/browser/auto-launch-controller.ts b/src/app/auto-launch-controller.ts similarity index 100% rename from src/browser/auto-launch-controller.ts rename to src/app/auto-launch-controller.ts diff --git a/src/browser/pop-out-window-handler.ts b/src/app/child-window-handler.ts similarity index 100% rename from src/browser/pop-out-window-handler.ts rename to src/app/child-window-handler.ts diff --git a/src/browser/chrome-flags.ts b/src/app/chrome-flags.ts similarity index 100% rename from src/browser/chrome-flags.ts rename to src/app/chrome-flags.ts diff --git a/src/browser/config-handler.ts b/src/app/config-handler.ts similarity index 100% rename from src/browser/config-handler.ts rename to src/app/config-handler.ts diff --git a/src/browser/crypto-library-handler.ts b/src/app/crypto-handler.ts similarity index 98% rename from src/browser/crypto-library-handler.ts rename to src/app/crypto-handler.ts index 697d6af0..ecde2d81 100644 --- a/src/browser/crypto-library-handler.ts +++ b/src/app/crypto-handler.ts @@ -46,7 +46,7 @@ const library = new Library((cryptoLibPath), { getVersion: [types.CString, []], }); -export interface ICryptoLib { +interface ICryptoLib { AESGCMEncrypt: (name: string, base64IV: string, base64AAD: string, base64Key: string, base64In: string) => string | null; AESGCMDecrypt: (base64IV: string, base64AAD: string, base64Key: string, base64In: string) => string | null; } diff --git a/src/browser/dialog-handler.ts b/src/app/dialog-handler.ts similarity index 100% rename from src/browser/dialog-handler.ts rename to src/app/dialog-handler.ts diff --git a/src/browser/main-api-handler.ts b/src/app/main-api-handler.ts similarity index 100% rename from src/browser/main-api-handler.ts rename to src/app/main-api-handler.ts diff --git a/src/browser/main.ts b/src/app/main.ts similarity index 98% rename from src/browser/main.ts rename to src/app/main.ts index 72e6a5b6..f2744c34 100644 --- a/src/browser/main.ts +++ b/src/app/main.ts @@ -9,7 +9,7 @@ import { setChromeFlags } from './chrome-flags'; import { config } from './config-handler'; import './dialog-handler'; import './main-api-handler'; -import { SpellChecker } from './spell-checker-handler'; +import { SpellChecker } from './spell-check-handler'; import { ICustomBrowserWindow, windowHandler } from './window-handler'; const allowMultiInstance: string | boolean = getCommandLineArgs(process.argv, '--multiInstance', true) || isDevEnv; diff --git a/src/browser/protocol-handler.ts b/src/app/protocol-handler.ts similarity index 100% rename from src/browser/protocol-handler.ts rename to src/app/protocol-handler.ts diff --git a/src/browser/reports.ts b/src/app/reports-handler.ts similarity index 62% rename from src/browser/reports.ts rename to src/app/reports-handler.ts index 3c41942e..0c71db32 100644 --- a/src/browser/reports.ts +++ b/src/app/reports-handler.ts @@ -1,11 +1,64 @@ +import * as archiver from 'archiver'; import { app, BrowserWindow, dialog, shell } from 'electron'; -import * as fs from 'fs'; - import * as electron from 'electron'; +import * as fs from 'fs'; +import * as path from 'path'; + import { isMac } from '../common/env'; import { i18n } from '../common/i18n'; -import { generateArchiveForDirectory } from '../common/utils'; +/** + * Archives files in the source directory + * that matches the given file extension + * + * @param source {String} source path + * @param destination {String} destination path + * @param fileExtensions {Array} array of file ext + * @return {Promise} + */ +const generateArchiveForDirectory = (source: string, destination: string, fileExtensions: string[]): Promise => { + + return new Promise((resolve, reject) => { + const output = fs.createWriteStream(destination); + const archive = archiver('zip', { zlib: { level: 9 } }); + + output.on('close', () => { + return resolve(); + }); + + archive.on('error', (err) => { + return reject(err); + }); + + archive.pipe(output); + + const files = fs.readdirSync(source); + files + .filter((file) => fileExtensions.indexOf(path.extname(file)) !== -1) + .forEach((file) => { + switch (path.extname(file)) { + case '.log': + archive.file(source + '/' + file, { name: 'logs/' + file }); + break; + case '.dmp': + case '.txt': // on Windows .txt files will be created as part of crash dump + archive.file(source + '/' + file, { name: 'crashes/' + file }); + break; + default: + break; + } + }); + + archive.finalize(); + }); +}; + +/** + * Compress and export logs stored under system log directory + * + * MacOS - /Library/Logs/Symphony/ + * Windows - AppData\Roaming\Symphony\logs + */ export const exportLogs = (): void => { const FILE_EXTENSIONS = [ '.log' ]; const MAC_LOGS_PATH = '/Library/Logs/Symphony/'; @@ -42,6 +95,9 @@ export const exportLogs = (): void => { }); }; +/** + * Compress and export crash dump stored under system crashes directory + */ export const exportCrashDumps = (): void => { const FILE_EXTENSIONS = isMac ? [ '.dmp' ] : [ '.dmp', '.txt' ]; const crashesDirectory = (electron.crashReporter as any).getCrashesDirectory(); diff --git a/src/browser/screen-snippet-handler.ts b/src/app/screen-snippet-handler.ts similarity index 100% rename from src/browser/screen-snippet-handler.ts rename to src/app/screen-snippet-handler.ts diff --git a/src/browser/spell-checker-handler.ts b/src/app/spell-check-handler.ts similarity index 100% rename from src/browser/spell-checker-handler.ts rename to src/app/spell-check-handler.ts diff --git a/src/browser/window-actions.ts b/src/app/window-actions.ts similarity index 99% rename from src/browser/window-actions.ts rename to src/app/window-actions.ts index a1d1457e..e55b2d5c 100644 --- a/src/browser/window-actions.ts +++ b/src/app/window-actions.ts @@ -2,7 +2,7 @@ import { BrowserWindow } from 'electron'; import { apiName, IBoundsChange, KeyCodes } from '../common/api-interface'; import { isWindowsOS } from '../common/env'; -import { throttle } from '../common/throttle'; +import { throttle } from '../common/utils'; import { config } from './config-handler'; import { ICustomBrowserWindow, windowHandler } from './window-handler'; import { showPopupMenu } from './window-utils'; diff --git a/src/browser/window-handler.ts b/src/app/window-handler.ts similarity index 99% rename from src/browser/window-handler.ts rename to src/app/window-handler.ts index eb17a8e1..4f6d60d5 100644 --- a/src/browser/window-handler.ts +++ b/src/app/window-handler.ts @@ -10,9 +10,9 @@ import { isMac, isWindowsOS } from '../common/env'; import { i18n } from '../common/i18n'; import { getCommandLineArgs, getGuid } from '../common/utils'; import { AppMenu } from './app-menu'; +import { handleChildWindow } from './child-window-handler'; import { config, IConfig } from './config-handler'; import { showNetworkConnectivityError } from './dialog-handler'; -import { handleChildWindow } from './pop-out-window-handler'; import { monitorWindowActions } from './window-actions'; import { createComponentWindow, getBounds, handleDownloadManager, injectStyles } from './window-utils'; diff --git a/src/browser/window-utils.ts b/src/app/window-utils.ts similarity index 100% rename from src/browser/window-utils.ts rename to src/app/window-utils.ts diff --git a/src/common/format-string.ts b/src/common/format-string.ts index a7cf2772..e69de29b 100644 --- a/src/common/format-string.ts +++ b/src/common/format-string.ts @@ -1,30 +0,0 @@ -/** - * 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; -}; \ No newline at end of file diff --git a/src/common/i18n-preload.ts b/src/common/i18n-preload.ts index 5b08eccb..c5e79337 100644 --- a/src/common/i18n-preload.ts +++ b/src/common/i18n-preload.ts @@ -1,4 +1,4 @@ -import { formatString } from './format-string'; +import { formatString } from './utils'; const localeCodeRegex = /^([a-z]{2})-([A-Z]{2})$/; diff --git a/src/common/i18n.ts b/src/common/i18n.ts index 6b714106..fdf1ca80 100644 --- a/src/common/i18n.ts +++ b/src/common/i18n.ts @@ -1,7 +1,7 @@ import * as fs from 'fs'; import * as path from 'path'; -import { formatString } from './format-string'; +import { formatString } from './utils'; const localeCodeRegex = /^([a-z]{2})-([A-Z]{2})$/; diff --git a/src/common/throttle.ts b/src/common/throttle.ts index cafd0f35..e69de29b 100644 --- a/src/common/throttle.ts +++ b/src/common/throttle.ts @@ -1,22 +0,0 @@ -/** - * 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); - } - }; -}; \ No newline at end of file diff --git a/src/common/utils.ts b/src/common/utils.ts index 24face44..1e96e484 100644 --- a/src/common/utils.ts +++ b/src/common/utils.ts @@ -1,7 +1,3 @@ -import * as archiver from 'archiver'; -import * as fs from 'fs'; -import * as path from 'path'; - // 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; @@ -52,7 +48,7 @@ const validate = (version: string): number => { * @param v2 * @returns {number} */ -const compareVersions = (v1: string, v2: string): number => { +export const compareVersions = (v1: string, v2: string): number => { if (validate(v1) === -1 || validate(v2) === -1) { return -1; } @@ -96,7 +92,7 @@ const compareVersions = (v1: string, v2: string): number => { * try finding arg that starts with argName. * @return {String} If found, returns the arg, otherwise null. */ -const getCommandLineArgs = (argv: string[], argName: string, exactMatch: boolean): string | 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}`); } @@ -120,7 +116,7 @@ const getCommandLineArgs = (argv: string[], argName: string, exactMatch: boolean * * @return {String} guid value in string */ -const getGuid = (): 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 @@ -135,7 +131,7 @@ const getGuid = (): string => { * @param object Object to be filtered * @param fields Fields to be picked */ -const pick = (object: object, fields: string[]) => { +export const pick = (object: object, fields: string[]) => { const obj = {}; for (const field of fields) { if (object[field]) { @@ -146,49 +142,55 @@ const pick = (object: object, fields: string[]) => { }; /** - * Archives files in the source directory - * that matches the given file extension + * Limits your function to be called at most every milliseconds * - * @param source {String} source path - * @param destination {String} destination path - * @param fileExtensions {Array} array of file ext - * @return {Promise} + * @param func + * @param wait + * @example const throttled = throttle(anyFunc, 500); */ -const generateArchiveForDirectory = (source: string, destination: string, fileExtensions: string[]): Promise => { +export const throttle = (func: (...args) => void, wait: number): (...args) => void => { + if (wait <= 0) { + throw Error('throttle: invalid throttleTime arg, must be a number: ' + wait); + } - return new Promise((resolve, reject) => { - const output = fs.createWriteStream(destination); - const archive = archiver('zip', { zlib: { level: 9 } }); + let isCalled: boolean = false; - output.on('close', () => { - return resolve(); - }); - - archive.on('error', (err) => { - return reject(err); - }); - - archive.pipe(output); - - const files = fs.readdirSync(source); - files - .filter((file) => fileExtensions.indexOf(path.extname(file)) !== -1) - .forEach((file) => { - switch (path.extname(file)) { - case '.log': - archive.file(source + '/' + file, { name: 'logs/' + file }); - break; - case '.dmp': - case '.txt': // on Windows .txt files will be created as part of crash dump - archive.file(source + '/' + file, { name: 'crashes/' + file }); - break; - default: - break; - } - }); - - archive.finalize(); - }); + return (...args) => { + if (!isCalled) { + func(...args); + isCalled = true; + setTimeout(() => isCalled = false, wait); + } + }; }; -export { compareVersions, getCommandLineArgs, getGuid, pick, generateArchiveForDirectory }; \ No newline at end of file +/** + * 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; +}; \ No newline at end of file diff --git a/src/renderer/ssf-api.ts b/src/renderer/ssf-api.ts index fe53ac2c..dcd402f4 100644 --- a/src/renderer/ssf-api.ts +++ b/src/renderer/ssf-api.ts @@ -1,6 +1,5 @@ import { ipcRenderer, remote } from 'electron'; -import { ICryptoLib } from '../browser/crypto-library-handler'; import { apiCmds, apiName, @@ -10,13 +9,18 @@ import { IScreenSnippet, KeyCodes, } from '../common/api-interface'; import { i18n, LocaleType } from '../common/i18n-preload'; -import { throttle } from '../common/throttle'; +import { throttle } from '../common/utils'; import { getSource } from './desktop-capturer'; let isAltKey: boolean = false; let isMenuOpen: boolean = false; let nextId = 0; +interface ICryptoLib { + AESGCMEncrypt: (name: string, base64IV: string, base64AAD: string, base64Key: string, base64In: string) => string | null; + AESGCMDecrypt: (base64IV: string, base64AAD: string, base64Key: string, base64In: string) => string | null; +} + interface ILocalObject { ipcRenderer; activityDetectionCallback?: (arg: IActivityDetection) => void; @@ -46,7 +50,7 @@ const throttledSetLocale = throttle((locale) => { let cryptoLib: ICryptoLib | null; try { - cryptoLib = remote.require('../browser/crypto-library-handler.js').cryptoLibrary; + cryptoLib = remote.require('../app/crypto-handler.js').cryptoLibrary; } catch (e) { cryptoLib = null; // tslint:disable-next-line