diff --git a/apps/gauzy/src/app/pages/invoices/invoices-received/invoices-received.component.ts b/apps/gauzy/src/app/pages/invoices/invoices-received/invoices-received.component.ts index 1e15c4b6fcf..9a7d4eaedc6 100644 --- a/apps/gauzy/src/app/pages/invoices/invoices-received/invoices-received.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoices-received/invoices-received.component.ts @@ -201,7 +201,7 @@ export class InvoicesReceivedComponent extends PaginationFilterBaseComponent imp where: { sentTo: organizationId, tenantId, - isEstimate: this.isEstimate === true ? 1 : 0, + isEstimate: this.isEstimate, invoiceDate: { startDate: toUTC(startDate).format('YYYY-MM-DD HH:mm:ss'), endDate: toUTC(endDate).format('YYYY-MM-DD HH:mm:ss') diff --git a/apps/gauzy/src/app/pages/invoices/invoices.component.ts b/apps/gauzy/src/app/pages/invoices/invoices.component.ts index 6760379b588..6296998b735 100644 --- a/apps/gauzy/src/app/pages/invoices/invoices.component.ts +++ b/apps/gauzy/src/app/pages/invoices/invoices.component.ts @@ -765,8 +765,8 @@ export class InvoicesComponent extends PaginationFilterBaseComponent implements where: { organizationId, tenantId, - isEstimate: this.isEstimate === true ? 1 : 0, - isArchived: this.includeArchived === true ? 1 : 0, + isEstimate: this.isEstimate, + isArchived: this.includeArchived, invoiceDate: { startDate: toUTC(startDate).format('YYYY-MM-DD HH:mm:ss'), endDate: toUTC(endDate).format('YYYY-MM-DD HH:mm:ss'), diff --git a/apps/gauzy/src/app/pages/jobs/proposal-template/proposal-template/proposal-template.component.html b/apps/gauzy/src/app/pages/jobs/proposal-template/proposal-template/proposal-template.component.html index 3ad8f408b0f..593b9aa667c 100644 --- a/apps/gauzy/src/app/pages/jobs/proposal-template/proposal-template/proposal-template.component.html +++ b/apps/gauzy/src/app/pages/jobs/proposal-template/proposal-template/proposal-template.component.html @@ -127,7 +127,7 @@

style="cursor: pointer" [settings]="smartTableSettings" [source]="smartTableSource" - (userRowSelect)="selectItem($event)" + (userRowSelect)="selectProposalTemplate($event)" >
diff --git a/apps/server/src/index.ts b/apps/server/src/index.ts index 0c4a9b55686..cb56a9b38fc 100644 --- a/apps/server/src/index.ts +++ b/apps/server/src/index.ts @@ -15,7 +15,7 @@ import { Menu, shell, MenuItemConstructorOptions, - screen, + screen } from 'electron'; import { environment } from './environments/environment'; @@ -32,7 +32,7 @@ console.log('Node Modules Path', path.join(__dirname, 'node_modules')); import { LocalStore, - apiServer, + DesktopServer, AppMenu, DesktopUpdater, TranslateLoader, @@ -50,7 +50,6 @@ import { ErrorReportRepository, DialogErrorHandler, AppError, - UIError, DialogOpenFile, ReverseUiProxy } from '@gauzy/desktop-libs'; @@ -59,7 +58,7 @@ import { createServerWindow, createSettingsWindow, SplashScreen, - createAboutWindow, + createAboutWindow } from '@gauzy/desktop-window'; import { initSentry } from './sentry'; import * as remoteMain from '@electron/remote/main'; @@ -93,7 +92,7 @@ let willQuit = false; const updater = new DesktopUpdater({ repository: process.env.REPO_NAME, owner: process.env.REPO_OWNER, - typeRelease: 'releases', + typeRelease: 'releases' }); const pathWindow: IPathWindow = { @@ -101,27 +100,23 @@ const pathWindow: IPathWindow = { ? path.join(__dirname, '../data/ui/index.html') : path.join(__dirname, './data/ui/index.html'), ui: path.join(__dirname, 'index.html'), - dir: app.isPackaged - ? path.join(__dirname, '../data/ui') - : path.join(__dirname, './data/ui'), - timeTrackerUi: path.join(__dirname, 'index.html'), + dir: app.isPackaged ? path.join(__dirname, '../data/ui') : path.join(__dirname, './data/ui'), + timeTrackerUi: path.join(__dirname, 'index.html') }; -const serverConfig: IServerConfig = new ServerConfig( - new ReadWriteFile(pathWindow) -); +const serverConfig: IServerConfig = new ServerConfig(new ReadWriteFile(pathWindow)); const reverseProxy: ILocalServer = new ReverseProxy(serverConfig); const reverseUiProxy: ILocalServer = new ReverseUiProxy(serverConfig); const executableName = path.basename(process.execPath); const eventErrorManager = ErrorEventManager.instance; -const report = new ErrorReport( - new ErrorReportRepository( - process.env.REPO_OWNER, - process.env.REPO_NAME - ) -); +const report = new ErrorReport(new ErrorReportRepository(process.env.REPO_OWNER, process.env.REPO_NAME)); + +const controller = new AbortController(); +const { signal } = controller; + +const desktopServer = new DesktopServer(); /* Load translations */ TranslateLoader.load(__dirname + '/assets/i18n/'); @@ -131,7 +126,7 @@ if (process.platform === 'win32') { } LocalStore.setFilePath({ - iconPath: path.join(__dirname, 'assets', 'icons', 'menu', 'icon.png'), + iconPath: path.join(__dirname, 'assets', 'icons', 'menu', 'icon.png') }); // Set unlimited listeners @@ -190,7 +185,6 @@ eventErrorManager.onSendReport(async (message) => { app.exit(0); break; } - }); eventErrorManager.onShowError(async (message) => { @@ -207,7 +201,7 @@ eventErrorManager.onShowError(async (message) => { // 👀 break; } -}) +}); const runSetup = async () => { // Set default configuration @@ -238,17 +232,8 @@ const runMainWindow = async () => { createTray(); } - new AppMenu( - null, - settingsWindow, - null, - null, - pathWindow, - serverWindow, - false - ); - const menuWindowSetting = - Menu.getApplicationMenu().getMenuItemById('window-setting'); + new AppMenu(null, settingsWindow, null, null, pathWindow, serverWindow, false); + const menuWindowSetting = Menu.getApplicationMenu().getMenuItemById('window-setting'); if (menuWindowSetting) menuWindowSetting.enabled = true; if (setupWindow) setupWindow.hide(); serverWindow.webContents.send('dashboard_ready', { @@ -266,22 +251,18 @@ const initializeConfig = async (val) => { } }; -const controller = new AbortController() -const { signal } = controller; -const runServer = (isRestart) => { - const envVal = getEnvApi(); - const uiPort = serverConfig.uiPort; +const runServer = async () => { try { - apiServer( - { - ui: path.join(__dirname, 'preload', 'ui-server.js'), - api: path.join(__dirname, 'api/main.js'), - }, + const envVal = getEnvApi(); + const uiPort = serverConfig.uiPort; + + // Instantiate API and UI servers + await desktopServer.start( + { api: path.join(__dirname, 'api/main.js'), ui: path.join(__dirname, 'preload', 'ui-server.js') }, envVal, serverWindow, - uiPort, - isRestart, - signal + signal, + uiPort ); } catch (error) { if (error.name === 'AbortError') { @@ -296,8 +277,7 @@ const getEnvApi = () => { const config = serverConfig.setting; serverConfig.update(); const addsConfig = LocalStore.getAdditionalConfig(); - const provider = - config.db === 'better-sqlite' ? 'better-sqlite3' : config.db; + const provider = config.db === 'better-sqlite' ? 'better-sqlite3' : config.db; return { IS_ELECTRON: 'true', DB_PATH: sqlite3filename, @@ -307,17 +287,15 @@ const getEnvApi = () => { DB_PORT: String(config[provider]?.dbPort), DB_NAME: config[provider]?.dbName, DB_USER: config[provider]?.dbUsername, - DB_PASS: config[provider]?.dbPassword, + DB_PASS: config[provider]?.dbPassword }), API_PORT: String(config.port), - ...addsConfig, + ...addsConfig }; }; const createTray = () => { - const iconNativePath = nativeImage.createFromPath( - path.join(__dirname, 'assets', 'icons', 'tray', 'icon.png') - ); + const iconNativePath = nativeImage.createFromPath(path.join(__dirname, 'assets', 'icons', 'tray', 'icon.png')); iconNativePath.resize({ width: 16, height: 16 }); tray = new Tray(iconNativePath); const serverMenu = contextMenu(); @@ -331,7 +309,7 @@ const contextMenu = () => { label: TranslateService.instant('MENU.OPEN_GA_BROWSER'), click() { shell.openExternal(serverConfig.uiUrl); - }, + } }, { id: 'check_for_update', @@ -339,58 +317,52 @@ const contextMenu = () => { click() { settingsWindow.show(); settingsWindow.webContents.send('goto_update'); - settingsWindow.webContents.send( - 'app_setting', - LocalStore.getApplicationConfig() - ); - }, + settingsWindow.webContents.send('app_setting', LocalStore.getApplicationConfig()); + } }, { - type: 'separator', + type: 'separator' }, { id: 'start_server', label: TranslateService.instant('MENU.START_SERVER'), - click() { - runServer(false); - }, + async click() { + await runServer(); + } }, { id: 'stop_server', label: TranslateService.instant('MENU.STOP_SERVER'), click() { - stopServer(false); - }, + stopServer(); + } }, { - type: 'separator', + type: 'separator' }, { id: 'server_help', label: TranslateService.instant('TIMER_TRACKER.MENU.HELP'), click() { shell.openExternal('https://gauzy.co'); - }, + } }, { id: 'gauzy-about', label: TranslateService.instant('MENU.ABOUT'), enabled: true, async click() { - const window: BrowserWindow = - await createAboutWindow( - pathWindow.ui - ); + const window: BrowserWindow = await createAboutWindow(pathWindow.ui); window.show(); - }, + } }, { id: 'server_exit', label: TranslateService.instant('BUTTONS.EXIT'), click() { app.quit(); - }, - }, + } + } ]; return serverMenu; @@ -400,41 +372,17 @@ ipcMain.on('start_server', async (event, arg) => { await initializeConfig(arg); }); -ipcMain.on('run_gauzy_server', (event, arg) => { +ipcMain.on('run_gauzy_server', async (event, arg) => { console.log('run Gauzy Server'); - runServer(false); + await runServer(); }); -const stopServer = (isRestart) => { - const config = serverConfig.setting; - console.log('api pid', config.apiPid); - console.log('api pid', config.uiPid); - if (config.apiPid) { - try { - process.kill(config.apiPid); - serverConfig.setting = { apiPid: null }; - serverWindow.webContents.send('log_state', { msg: 'Api stopped' }); - } catch (error) { - throw new UIError('400', error, 'KILL-API-SERVER'); - } - } - if (config.uiPid) { - try { - process.kill(config.uiPid); - serverConfig.setting = { uiPid: null }; - serverWindow.webContents.send('log_state', { msg: 'UI stopped' }); - if (isRestart) { - runServer(true); - } - } catch (error) { - throw new UIError('400', error, 'KILL-UI-SERVER'); - } - } - serverWindow.webContents.send('running_state', false); +const stopServer = () => { + desktopServer.stop(); }; ipcMain.on('stop_gauzy_server', (event, arg) => { - stopServer(false); + stopServer(); }); app.on('ready', async () => { @@ -447,7 +395,7 @@ app.on('ready', async () => { launchAtStartup(true, false); } global.variableGlobal = { - API_BASE_URL: serverConfig.apiPort, + API_BASE_URL: serverConfig.apiUrl, IS_INTEGRATED_DESKTOP: false }; if (!settingsWindow) { @@ -461,33 +409,24 @@ app.on('ready', async () => { throw new AppError('MAINWININIT', error); } TranslateService.onLanguageChange(() => { - const menuWindowSetting = - Menu.getApplicationMenu().getMenuItemById('window-setting'); - new AppMenu( - null, - settingsWindow, - null, - null, - pathWindow, - serverWindow, - false - ); + const menuWindowSetting = Menu.getApplicationMenu().getMenuItemById('window-setting'); + new AppMenu(null, settingsWindow, null, null, pathWindow, serverWindow, false); if (tray) tray.destroy(); createTray(); if (menuWindowSetting) menuWindowSetting.enabled = true; - }) + }); }); -ipcMain.on('restart_app', (event, arg) => { +ipcMain.on('restart_app', async (event, arg) => { console.log('Restarting Server', arg); - if (arg.apiPid) delete arg.apiPid; - if (arg.uiPid) delete arg.uiPid; serverConfig.setting = arg; serverConfig.update(); - event.sender.send('resp_msg', { type: 'update_config', status: 'success' }); - if (isServerRun) { - stopServer(true); - } + event.sender.send('resp_msg', { + type: 'update_config', + status: 'success', + ...(!desktopServer.running && { message: 'TOASTR.MESSAGE.UPDATED' }) + }); + await desktopServer.restart(); }); ipcMain.on('save_additional_setting', (event, arg) => { @@ -516,23 +455,22 @@ ipcMain.on('check_database_connection', async (event, arg) => { databaseOptions = { client: 'sqlite', connection: { - filename: sqlite3filename, - }, + filename: sqlite3filename + } }; } const dbConn = require('knex')(databaseOptions); await dbConn.raw('select 1+1 as result'); event.sender.send('database_status', { status: true, - message: TranslateService.instant( - 'TIMER_TRACKER.DIALOG.CONNECTION_DRIVER', - { driver: provider === 'postgres' ? 'PostgresSQL' : 'SQLite' } - ) + message: TranslateService.instant('TIMER_TRACKER.DIALOG.CONNECTION_DRIVER', { + driver: provider === 'postgres' ? 'PostgresSQL' : 'SQLite' + }) }); } catch (error) { event.sender.send('database_status', { status: false, - message: error.message, + message: error.message }); } }); @@ -572,7 +510,7 @@ ipcMain.on('loading_state', (event, arg) => { ipcMain.on('expand_window', (event, arg) => { const display = screen.getPrimaryDisplay(); - const { width, height } = display.workArea; + const { height, width } = display.workAreaSize; console.log('width ', width); console.log('height ', height); const wx = 640; @@ -593,15 +531,15 @@ ipcMain.on('expand_window', (event, arg) => { break; default: { - serverWindow.setBounds( - { - width: wx, - height: hx, - x: (width - wx) * 0.5, - y: (height - hx) * 0.5 - }, - true - ); + serverWindow.setBounds( + { + width: wx, + height: hx, + x: (width - wx) * 0.5, + y: (height - hx) * 0.5 + }, + true + ); } break; } @@ -634,15 +572,15 @@ app.on('before-quit', async (e) => { const button = await exitConfirmationDialog.show(); if (button.response === 0) { // Stop the server from main - stopServer(false); + stopServer(); // Mark as will quit willQuit = true; - }; + } } else { // soft download cancellation try { updater.cancel(); - } catch (e) { } + } catch (e) {} app.exit(0); } }); @@ -657,8 +595,8 @@ ipcMain.on('update_app_setting', (event, arg) => { }); app.on('browser-window-created', (_, window) => { - require("@electron/remote/main").enable(window.webContents) -}) + require('@electron/remote/main').enable(window.webContents); +}); ipcMain.handle('PREFERRED_LANGUAGE', (event, arg) => { const setting = LocalStore.getStore('appSetting'); @@ -727,9 +665,9 @@ ipcMain.on('save_encrypted_file', (event, value) => { serverConfig.setting = { secureProxy }; - event.reply('app_setting', LocalStore.getApplicationConfig()); + event.sender.send('app_setting', LocalStore.getApplicationConfig()); } } catch (error) { console.error(error); } -}) +}); diff --git a/apps/server/src/preload/desktop-server-api.ts b/apps/server/src/preload/desktop-server-api.ts index 9dbfb1650a2..e9852e2d10a 100644 --- a/apps/server/src/preload/desktop-server-api.ts +++ b/apps/server/src/preload/desktop-server-api.ts @@ -1,85 +1,99 @@ -import { fork } from 'child_process'; +import { fork, ChildProcessWithoutNullStreams } from 'child_process'; import { LocalStore } from '@gauzy/desktop-libs'; -export interface IEnvApi { - IS_ELECTRON: string, - DB_PATH: string, - DB_TYPE: string, - DB_HOST: string, - DB_PORT: string, - DB_NAME: string, - DB_USER: string, - DB_PASS: string, - API_PORT: string, - API_HOST: string, - API_BASE_URL: string +interface IEnvApi { + IS_ELECTRON: string; + DB_PATH: string; + DB_TYPE: string; + DB_HOST?: string; + DB_PORT?: string; + DB_NAME?: string; + DB_USER?: string; + DB_PASS?: string; + API_PORT: string; + API_HOST: string; + API_BASE_URL: string; } +class ApiServerProcessFactory { + public static createApiServerProcess(): ChildProcessWithoutNullStreams { + try { + const { apiPath, db, dbName, dbPassword, dbUsername, dbPort, port, dbPath, dbHost, apiBaseUrl, apiHost } = + this.prepareServerApi(); -const runServerApi = () => { - const { apiPath, db, dbName, dbPassword, dbUsername, dbPort, port, dbPath, dbHost, apiBaseUrl, apiHost } = prepareServerApi(); - const apiEnv: IEnvApi = { - IS_ELECTRON: 'true', - DB_PATH: dbPath, - DB_TYPE: db, - DB_HOST: dbHost, - DB_PORT: String(dbPort), - DB_NAME: dbName, - DB_USER: dbUsername, - DB_PASS: dbPassword, - API_PORT: String(port), - API_HOST: apiHost, - API_BASE_URL: apiBaseUrl - } - const uiService = fork(apiPath, { - silent: true, detached: true, env: { - ...process.env, - IS_ELECTRON: apiEnv.IS_ELECTRON - }}); - uiService.stdout.on('data', (data) => { - console.log('SERVER API STATE LOGS -> ', data.toString()); - uiService.unref(); - process.exit(0); - }); + const apiEnv: IEnvApi = { + IS_ELECTRON: 'true', + DB_PATH: dbPath, + DB_TYPE: db, + DB_HOST: dbHost || '', + DB_PORT: dbPort ? String(dbPort) : '', + DB_NAME: dbName || '', + DB_USER: dbUsername || '', + DB_PASS: dbPassword || '', + API_PORT: String(port), + API_HOST: apiHost, + API_BASE_URL: apiBaseUrl + }; + + const uiService = fork(apiPath, { + silent: true, + detached: true, + env: { + ...process.env, + ...apiEnv + } + }); + + uiService.stdout.on('data', (data) => { + console.log('SERVER API STATE LOGS -> ', data.toString()); + uiService.unref(); + process.exit(0); + }); + + return uiService; + } catch (error) { + console.error('[CRITICAL::ERROR]: Running API server failed:', error); + } + } + + private static prepareServerApi(): { + apiPath: string; + db: string; + dbPort: number | null; + dbName: string | null; + dbUsername: string | null; + dbPassword: string | null; + port: number; + dbPath: string; + dbHost: string | null; + apiBaseUrl: string; + apiHost: string; + } { + const { port, db, apiPath, dbPath, postgres, apiBaseUrl } = LocalStore.getStore('configs'); + + return { + apiPath, + db, + dbPort: postgres?.dbPort || null, + dbName: postgres?.dbName || null, + dbPassword: postgres?.dbPassword || null, + dbUsername: postgres?.dbUsername || null, + dbHost: postgres?.dbHost || null, + port, + dbPath, + apiBaseUrl, + apiHost: '0.0.0.0' + }; + } } -const prepareServerApi = (): { - apiPath: string, - db: string, - dbPort: number | null, - dbName: string | null, - dbUsername: string | null, - dbPassword: string | null, - port: number, - dbPath: string, - dbHost: string | null, - apiBaseUrl: string, - apiHost: string -} => { - const { - port, - db, - apiPath, - dbPath, - postgres, - apiBaseUrl - } = LocalStore.getStore('configs'); - return { - apiPath, - db, - dbPort: postgres?.dbPort || null, - dbName: postgres?.dbName || null, - dbPassword: postgres?.dbPassword || null, - dbUsername: postgres?.dbUsername || null, - dbHost: postgres?.dbHost || null, - port, - dbPath, - apiBaseUrl, - apiHost: '0.0.0.0' - }; +class App { + public static main(): void { + ApiServerProcessFactory.createApiServerProcess(); + } } export default function () { - console.log('Before Run Api Server'); - runServerApi(); + console.log('Before running API Server'); + App.main(); } diff --git a/apps/server/src/preload/desktop-server-ui.ts b/apps/server/src/preload/desktop-server-ui.ts index 2ad9f5ce5d6..6acb4fa0ea2 100644 --- a/apps/server/src/preload/desktop-server-ui.ts +++ b/apps/server/src/preload/desktop-server-ui.ts @@ -1,38 +1,59 @@ -import { spawn } from 'child_process'; -import * as path from 'path'; +import { spawn, ChildProcessWithoutNullStreams } from 'child_process'; +import path from 'path'; import { app } from 'electron'; import os from 'os'; -const appPath = app.getPath('userData'); -const runServerUI = () => { - try { - const { uiPath } = prepareServerUi(); - console.log('ui path', uiPath); - const uiService = spawn(uiPath, { detached: true }); +class ServerProcessFactory { + public static createUiServerProcess(): ChildProcessWithoutNullStreams { + const appPath = app.getPath('userData'); + const uiPath = this.prepareServerUi(appPath); + console.log('UI Path:', uiPath); + + const uiService = spawn(uiPath, { detached: true, stdio: 'pipe' }); + uiService.stdout.on('data', (data) => { console.log('SERVER UI STATE LOGS -> ', data.toString()); }); - } catch (error) { - console.log('Error in runServerUI', error); + + uiService.stderr.on('data', (data) => { + console.error('SERVER UI ERROR LOGS -> ', data.toString()); + }); + + uiService.on('error', (error) => { + console.error('Failed to start UI server:', error); + }); + + uiService.on('exit', (code, signal) => { + console.log(`UI server exited with code ${code} and signal ${signal}`); + }); + + return uiService; + } + + private static prepareServerUi(appPath: string): string { + let appName = ''; + switch (os.platform()) { + case 'win32': + appName = `${process.env.NAME}.exe`; + break; + case 'darwin': + appName = process.env.NAME || ''; + break; + default: + break; + } + return path.join(appPath, appName); } -}; - -const prepareServerUi = (): { - uiPath: string; -} => { - let appName: string = ''; - switch (os.platform()) { - case 'win32': - appName = `${process.env.NAME}.exe`; - break; - case 'darwin': - appName = process.env.NAME; - break; - default: - break; +} + +class App { + public static main(): void { + try { + ServerProcessFactory.createUiServerProcess(); + } catch (error) { + console.error('[CRITICAL::ERROR]: Starting server:', error); + } } - return { - uiPath: path.join(appPath, appName) - }; -}; -runServerUI(); +} + +App.main(); diff --git a/apps/server/src/preload/loginPage.ts b/apps/server/src/preload/loginPage.ts deleted file mode 100644 index 5c0b94f1647..00000000000 --- a/apps/server/src/preload/loginPage.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { ipcRenderer } from 'electron'; - -ipcRenderer.on('hide_register', () => { - const waitElement = setInterval(() => { - try { - document - .querySelector('[aria-label="Register"]') - .setAttribute('style', 'display: none'); - clearInterval(waitElement); - } catch (error) {} - }); -}); diff --git a/apps/server/src/preload/server-manager.ts b/apps/server/src/preload/server-manager.ts new file mode 100644 index 00000000000..3530fe015b2 --- /dev/null +++ b/apps/server/src/preload/server-manager.ts @@ -0,0 +1,17 @@ +import { StaticFileServer } from './static-file-server'; + +export class ServerManager { + private staticFileServer: StaticFileServer; + + public constructor() { + this.staticFileServer = StaticFileServer.getInstance(); + } + + public runServer(port: number) { + try { + this.staticFileServer.startServer(port); + } catch (error) { + console.error('[CRITICAL::ERROR]: Starting server:', error); + } + } +} diff --git a/apps/server/src/preload/static-file-server.ts b/apps/server/src/preload/static-file-server.ts new file mode 100644 index 00000000000..100b550a2ec --- /dev/null +++ b/apps/server/src/preload/static-file-server.ts @@ -0,0 +1,54 @@ +import http from 'http'; +import path from 'path'; +import { parse } from 'url'; +import { Server as NodeStaticServer } from 'node-static'; +import { IncomingMessage, ServerResponse } from 'http'; + +export class StaticFileServer { + private static instance: StaticFileServer; + private fileServer: NodeStaticServer; + private isPackaged: boolean; + private dirUi: string; + + private constructor() { + this.isPackaged = process.env.isPackaged === 'true'; + this.dirUi = this.isPackaged + ? path.join(__dirname, '..', '..', 'data', 'ui') + : path.join(__dirname, '..', 'data', 'ui'); + this.fileServer = new NodeStaticServer(this.dirUi); + } + + public serveFile(req: IncomingMessage, res: ServerResponse): void { + this.fileServer.serve(req, res, (err: any | null, result: any) => { + if (err) { + console.error(`Error serving ${req.url} - ${err.message}`); + res.writeHead(err.status || 500, err.headers || {}); + res.end(); + } else { + console.log('UI server started'); + console.log(JSON.stringify(parse(req.url || '', true).query)); + } + }); + } + + public startServer(port: number): void { + const server = http.createServer((req, res) => this.serveFile(req, res)); + + server.on('listening', () => { + console.log(`Listening on port ${port}`); + }); + + server.on('error', (error: Error) => { + console.error(`[CRITICAL::ERROR]: Server error: ${error}`); + }); + + server.listen(port, '0.0.0.0'); + } + + public static getInstance(): StaticFileServer { + if (!StaticFileServer.instance) { + StaticFileServer.instance = new StaticFileServer(); + } + return StaticFileServer.instance; + } +} diff --git a/apps/server/src/preload/ui-server.ts b/apps/server/src/preload/ui-server.ts index 7ba5cae1c85..a8c1dec3322 100644 --- a/apps/server/src/preload/ui-server.ts +++ b/apps/server/src/preload/ui-server.ts @@ -1,24 +1,17 @@ -import http from 'http'; -import * as path from 'path'; -const serverStatic = require('node-static'); -const dirUi = - process.env.isPackaged === 'true' - ? path.join(__dirname, '..', '..', 'data', 'ui') - : path.join(__dirname, '..', 'data', 'ui'); -const file = new serverStatic.Server(dirUi); -const url = require('url'); -console.log('server started'); +import { ServerManager } from './server-manager'; -async function runServer() { - const portUi = process.env.uiPort ? Number(process.env.uiPort) : 4200; - http.createServer(function (req, res) { - file.serve(req, res); - console.log('server ui started'); - console.log(url.parse(req.url, true).query); - }).listen(portUi, '0.0.0.0', () => { - console.log(`listen ui on port ${portUi}`); - }); - return true; +class App { + public static main(): void { + try { + const portUi = process.env.UI_PORT ? Number(process.env.UI_PORT) : 4200; + const serverManager = new ServerManager(); + + serverManager.runServer(portUi); + } catch (error) { + console.error('[CRITICAL::ERROR]: Starting server:', error); + } + } } -runServer(); +// Call the function to start the server when this module is executed +App.main(); diff --git a/package.json b/package.json index d4bca4333f8..39e74dca299 100644 --- a/package.json +++ b/package.json @@ -1,440 +1,440 @@ { - "name": "ever-gauzy", - "version": "0.1.0", - "description": "Ever Gauzy - Business Management Platform (ERP/CRM/HRM)", - "license": "AGPL-3.0", - "homepage": "https://gauzy.co", - "repository": { - "type": "git", - "url": "https://github.com/ever-co/ever-gauzy.git" - }, - "bugs": { - "url": "https://github.com/ever-co/ever-gauzy/issues" - }, - "private": true, - "author": { - "name": "Ever Co. LTD", - "email": "ever@ever.co", - "url": "https://ever.co" - }, - "keywords": [], - "scripts": { - "prepare:husky": "npx husky install .husky", - "ng": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn nx", - "ng:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn nx", - "ng:docker": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn nx", - "ng:ci": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn nx", - "config": "yarn ts-node ./.scripts/configure.ts", - "config:dev": "yarn run config -- --environment=dev", - "config:prod": "yarn run config -- --environment=prod", - "start": "yarn build:package:all && yarn concurrently --raw --kill-others \"yarn start:api\" \"yarn start:gauzy\"", - "start:prod": "yarn build:package:all && yarn concurrently --raw --kill-others \"yarn start:api:prod\" \"yarn start:gauzy:prod\"", - "start:gauzy": "yarn run postinstall.web && yarn run config:dev && yarn ng serve gauzy --open", - "start:gauzy:forever": "yarn run config:dev && forever start node_modules/@angular/cli/bin/ng serve gauzy --disable-host-check --host 0.0.0.0", - "start:gauzy:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn build:package:all && yarn build:gauzy && yarn ts-node ./apps/gauzy/src/pm2bootstrap.ts", - "start:gauzy:prod": "yarn run config:prod && yarn ng serve gauzy --configuration production --disable-host-check --host 0.0.0.0 --prod", - "start:api": "yarn ng serve api", - "start:api:prod": "yarn ng:prod serve api --host 0.0.0.0 -c=production --prod", - "start:api:ci": "yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci serve api -c=production --prod", - "start:api:forever": "forever start node_modules/@angular/cli/bin/ng serve api --host 0.0.0.0", - "start:api:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn run build:api && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/pm2bootstrap.ts", - "start:api:core": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn --cwd ./packages/core start:api", - "migration:run": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:run", - "migration:revert": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:revert", - "migration:generate": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:generate", - "migration:create": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:create", - "migration:command": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core", - "seed": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed.ts", - "seed:ever": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-ever.ts", - "seed:all": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-all.ts", - "seed:jobs": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-jobs.ts", - "seed:module": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-module.ts --name", - "seed:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:prod && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed.ts", - "bootstrap": "yarn install && yarn lerna bootstrap", - "prebuild": "rimraf dist coverage", - "build": "yarn build:package:all && concurrently --raw \"yarn build:api\" \"yarn build:gauzy\"", - "build:lerna": "yarn lerna run --parallel build", - "build:prod": "yarn build:package:all && concurrently --raw \"yarn build:api:prod\" \"yarn build:gauzy:prod\"", - "build:gauzy": "yarn run postinstall.web && yarn run config:dev && yarn ng build gauzy", - "build:gauzy:prod": "yarn run config:prod && yarn ng:prod build gauzy -c=production --prod --verbose", - "build:gauzy:prod:docker": "yarn run config:prod && yarn ng:docker build gauzy -c=production --prod --verbose", - "build:gauzy:prod:ci": "yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci build gauzy -c=production --prod --verbose", - "build:api": "yarn ng build api", - "build:api:prod": "yarn ng:prod build api -c=production --prod", - "build:api:prod:docker": "yarn ng:docker build api -c=production --prod", - "build:api:prod:ci": "yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci build api -c=production --prod", - "bundle-report": "yarn run config:prod && yarn ng:prod build -c=production --stats-json && webpack-bundle-analyzer dist/apps/gauzy/stats.json", - "commit": "git-cz", - "commit:lint": "commitlint -E HUSKY_GIT_PARAMS", - "semantic-release": "semantic-release", - "test": "yarn run postinstall.web && yarn run config:dev && yarn ng test", - "lint": "yarn run config:dev && yarn ng lint && yarn ng lint", - "e2e": "yarn run postinstall.web && yarn run config:dev && yarn ng e2e --browser chrome", - "e2e:ci": "yarn run postinstall.web && yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci e2e -c=production --prod --headless", - "affected:apps": "yarn nx affected:apps", - "affected:libs": "yarn nx affected:libs", - "affected:build": "yarn nx affected:build", - "affected:e2e": "yarn nx affected:e2e", - "affected:test": "yarn nx affected:test", - "affected:lint": "yarn nx affected:lint", - "affected:dep-graph": "yarn nx affected:dep-graph", - "affected": "yarn nx affected", - "format": "yarn nx format:write", - "format:write": "yarn nx format:write", - "format:check": "yarn nx format:check", - "update": "yarn ng update @nrwl/workspace", - "update:check": "yarn ng update", - "workspace-schematic": "yarn nx workspace-schematic", - "dep-graph": "yarn nx dep-graph", - "help": "yarn nx help", - "doc:build": "compodoc -p tsconfig.json -d dist/docs", - "doc:serve": "compodoc -s -d dist/docs", - "doc:build-serve": "compodoc -p tsconfig.json -d docs -s", - "postinstall.electron": "yarn electron-builder install-app-deps && yarn node tools/electron/postinstall", - "postinstall.web": "yarn node ./decorate-angular-cli.js && yarn npx ngcc --properties es2016 browser module main --first-only --create-ivy-entry-points && yarn node tools/web/postinstall", - "build:desktop": "cross-env NODE_ENV=production yarn run copy-files-i18n-desktop && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:desktop:prod && yarn run pack:desktop && yarn run generate:icons:desktop --environment=prod && yarn ng:prod build desktop --prod --base-href ./ && yarn run prepare:desktop && yarn ng:prod build desktop-api --prod && yarn ng:prod build api-desktop --prod --output-path=dist/apps/desktop/desktop-api && yarn ng:prod build desktop-ui --prod --base-href ./ && yarn run copy-files-desktop && yarn run copy-assets-gauzy", - "build:desktop:local": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && electron dist/apps/desktop", - "build:desktop:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/desktop", - "build:desktop:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop", - "build:desktop:mac": "yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop", - "build:desktop:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop", - "build:desktop:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop", - "build:desktop:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop", - "build:desktop:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop", - "build:desktop:mac:release": "yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/desktop", - "prepare:desktop": "yarn run postinstall.electron && tsc -p apps/desktop/tsconfig.json", - "serve:desktop.target": "yarn ng serve desktop", - "serve:desktop": "wait-on http-get://localhost:4200/ && electron apps/desktop/src --serve", - "start:desktop": "yarn run prepare:desktop && npm-run-all -p serve.electron.gauzy-desktop.target serve.electron.gauzy-desktop", - "build:desktop:mac:quick": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop", - "build:desktop:local:quick": "yarn electron dist/apps/desktop --prod", - "build:desktop:windows:quick": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --windows --project dist/apps/desktop", - "build:sqlite:mac": "cd node_modules/sqlite3 && HOME=~/.electron-gyp node-pre-gyp rebuild --target=8.3.0 --arch=x64 --dist-url=https://electronjs.org/headers", - "build:sqlite:windows": "cd node_modules/sqlite3 && cross-env HOME=~/.electron-gyp node-pre-gyp rebuild --target=8.3.0 --arch=x64 --target_platform=win32 --dist-url=https://electronjs.org/headers", - "debug:desktop:app:mac": "lldb ./dist/apps/desktop-packages/mac/GauzyDesktop.app && run", - "start:desktop:ui": "yarn run postinstall.web && yarn ng serve desktop-ui", - "build:desktop:ui": "yarn run postinstall.web && yarn ng:prod build desktop-ui --prod --base-href ./", - "prepare:desktop:dev": "yarn run postinstall.electron && tsc -p apps/desktop/tsconfig.dev.json", - "start:api:desktop": "yarn ng serve api-desktop", - "deploy:desktop:mac": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish always --project dist/apps/desktop", - "build:package:auth": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/auth build", - "build:package:auth:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/auth build", - "build:package:core": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core build", - "build:package:core:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core build", - "build:package:common": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common build", - "build:package:common:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common build", - "build:package:common-angular": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common-angular build", - "build:package:common-angular:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common-angular build", - "build:package:contracts": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/contracts build", - "build:package:contracts:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/contracts build", - "build:package:config": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/config build", - "build:package:config:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/config build:prod", - "build:package:plugin": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugin build", - "build:package:plugin:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugin build", - "build:package:plugins": "yarn run build:package:plugin:integration-ai && yarn run build:package:plugin:integration-hubstaff && yarn run build:package:plugin:integration-upwork && yarn run build:package:plugin:integration-github && yarn run build:package:plugin:integration-jira", - "build:package:plugins:prod": "yarn run build:package:plugin:integration-ai:prod && yarn run build:package:plugin:integration-hubstaff:prod && yarn run build:package:plugin:integration-upwork:prod && yarn run build:package:plugin:product-reviews:prod && yarn run build:package:plugin:integration-github:prod && yarn run build:package:plugin:integration-jira:prod", - "build:package:plugin:integration-ai": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-ai build", - "build:package:plugin:integration-ai:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-ai build", - "build:package:plugin:integration-hubstaff": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-hubstaff build", - "build:package:plugin:integration-hubstaff:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-hubstaff build", - "build:package:plugin:integration-upwork": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-upwork build", - "build:package:plugin:integration-upwork:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-upwork build", - "build:package:plugin:integration-github": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-github build", - "build:package:plugin:integration-github:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-github build", - "build:package:plugin:integration-jira": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-jira build", - "build:package:plugin:integration-jira:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-jira build", - "build:package:plugin:product-reviews": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/product-reviews build", - "build:package:plugin:product-reviews:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/product-reviews build", - "build:package:plugin:knowledge-base": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/knowledge-base build", - "build:package:plugin:knowledge-base:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/knowledge-base build", - "build:package:plugin:changelog": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/changelog build", - "build:package:plugin:changelog:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/changelog build", - "build:package:plugin:integration-wakatime": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-wakatime build", - "build:package:plugin:integration-wakatime:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-wakatime build", - "build:package:all": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:common-angular && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:product-reviews && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog && yarn build:package:desktop-libs && yarn build:package:plugin:integration-wakatime && yarn build:package:desktop-ui-lib", - "build:package:desktop-window": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-window build", - "build:package:desktop-libs": "yarn run build:package:desktop-window && cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-libs build", - "build:package:api": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog", - "build:package:api:prod": "yarn run build:package:contracts:prod && yarn run build:package:common:prod && yarn run build:package:config:prod && yarn run build:package:plugin:prod && yarn run build:package:plugins:prod && yarn run build:package:auth:prod && yarn run build:package:core:prod && yarn run build:package:plugin:knowledge-base:prod && yarn run build:package:plugin:changelog:prod", - "build:package:gauzy": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:common-angular && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog", - "build:package:desktop-ui-lib": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-ui-lib build", - "copy-files-desktop": "copyfiles -f packages/core/src/**/*.gql dist/apps/desktop/data/", - "build:desktop-timer": "cross-env NODE_ENV=production yarn copy-files-i18n-desktop-timer && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:desktop-timer:prod && yarn run pack:desktop-timer && yarn run generate:icons:desktop-timer --environment=prod && yarn ng:prod build desktop-timer --prod --base-href ./ && yarn run prepare:desktop-timer && yarn ng:prod build api-desktop --prod --output-path=dist/apps/desktop-timer/desktop-api && yarn run copy-assets-gauzy-timer", - "prepare:desktop-timer": "yarn run postinstall.electron && tsc -p apps/desktop-timer/tsconfig.json", - "build:desktop-timer:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/desktop-timer", - "build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop-timer", - "build:desktop-timer:mac": "yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop-timer", - "build:desktop-timer:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop-timer", - "build:desktop-timer:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop-timer", - "build:desktop-timer:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", - "build:desktop-timer:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", - "build:desktop-timer:mac:release": "yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/desktop-timer", - "copy-assets-gauzy": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop/data/sound/", - "copy-assets-gauzy-timer": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop-timer/data/sound/", - "config:electron": "yarn ts-node ./.scripts/electron.env.ts", - "config:server:prod": "yarn run config:electron -- --environment=prod --desktop=server", - "config:desktop:prod": "yarn run config:electron -- --environment=prod --desktop=desktop", - "config:desktop-timer:prod": "yarn run config:electron -- --environment=prod --desktop=desktop-timer", - "prepare:gauzy-server": "yarn run postinstall.electron && tsc -p apps/server/tsconfig.json", - "build:gauzy-server": "cross-env NODE_ENV=production yarn run copy-files-i18n-server && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:server:prod && yarn run pack:server && yarn run generate:icons:server --environment=prod && yarn ng:prod build gauzy-server --prod --base-href ./ && yarn run prepare:gauzy-server && yarn ng:prod build gauzy-server-ui --prod --base-href ./ && yarn ng:prod build gauzy-server-api --prod && yarn run copy-files-gauzy-server", - "copy-files-gauzy-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-server/data/", - "build:gauzy-server:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/gauzy-server", - "build:gauzy-server:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/gauzy-server", - "build:gauzy-server:mac": "yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/gauzy-server", - "build:gauzy-server:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/gauzy-server", - "build:gauzy-server:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/gauzy-server", - "build:gauzy-server:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/gauzy-server", - "build:gauzy-server:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/gauzy-server", - "build:gauzy-server:mac:release": "yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/gauzy-server", - "quick:build:gauzy-server": "yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --mac --project dist/apps/gauzy-server", - "copy-files-i18n-desktop-timer": "yarn run download:translations --desktop=desktop-timer", - "copy-files-i18n-desktop": "yarn run download:translations --desktop=desktop", - "copy-files-i18n-server": "yarn run download:translations --desktop=server", - "generate:icons": "yarn ts-node .scripts/icon-utils/icon-factory.ts", - "generate:icons:desktop-timer": "yarn run generate:icons --desktop=desktop-timer", - "generate:icons:desktop": "yarn run generate:icons --desktop=desktop", - "generate:icons:server": "yarn run generate:icons --desktop=server", - "pack": "yarn ts-node .scripts/electron-package-utils/package-util.ts", - "pack:desktop-timer": "yarn run pack --desktop=desktop-timer", - "pack:desktop": "yarn run pack --desktop=desktop", - "pack:server": "yarn run pack --desktop=server", - "download:translations": "yarn ts-node .scripts/translation/translation-util.ts" - }, - "config": { - "commitizen": { - "path": "cz-conventional-changelog" - } - }, - "commitlint": { - "extends": [ - "@commitlint/config-conventional" - ] - }, - "husky": { - "hooks": { - "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", - "pre-commit": "pretty-quick --no-verify --staged" - } - }, - "lint-staged": {}, - "release": { - "verifyConditions": [ - "@semantic-release/changelog", - "@semantic-release/npm", - "@semantic-release/git", - "@semantic-release/github" - ], - "prepare": [ - "@semantic-release/changelog", - "@semantic-release/npm", - "@semantic-release/git" - ], - "publish": [ - "@semantic-release/github" - ], - "generateNotes": { - "preset": "angular" - }, - "npmPublish": false - }, - "workspaces": { - "packages": [ - "libs/*", - "apps/*", - "tools", - "packages/*", - "packages/plugins/*" - ], - "nohoist": [ - "**/@types/jasmine", - "**/@types/jasminewd2", - "**/@angular*/**", - "**/@ngtools/**" - ] - }, - "resolutions": { - "@angular-devkit/architect": "^0.1602.11", - "@angular-devkit/build-angular": "^16.2.11", - "@angular-devkit/core": "^16.2.11", - "rxjs": "^7.4.0", - "autoprefixer": "10.4.14" - }, - "dependencies": { - "@angular/animations": "^16.2.12", - "@angular/cdk": "^16.2.12", - "@angular/common": "^16.2.12", - "@angular/compiler": "^16.2.12", - "@angular/core": "^16.2.12", - "@angular/forms": "^16.2.12", - "@angular/language-service": "^16.2.12", - "@angular/material": "^16.2.12", - "@angular/platform-browser": "^16.2.12", - "@angular/platform-browser-dynamic": "^16.2.12", - "@angular/router": "^16.2.12", - "@angular/service-worker": "^16.2.12", - "@nebular/auth": "^12.0.0", - "@nebular/bootstrap": "^9.1.0-rc.6", - "@nebular/eva-icons": "^12.0.0", - "@nebular/security": "^12.0.0", - "@nebular/theme": "^12.0.0", - "@ng-select/ng-select": "^11.2.0", - "angular2-smart-table": "^3.2.0", - "autoprefixer": "10.4.14", - "bcrypt": "^5.1.0", - "dotenv": "^16.0.3", - "ffi-napi": "^4.0.3", - "iconv": "^3.0.1", - "jsdom": "^23.0.1", - "lodash-es": "^4.17.21", - "parse5": "^7.1.2", - "rxjs": "^7.4.0", - "unleash": "^2.0.2", - "yargs": "^17.5.0" - }, - "devDependencies": { - "@angular-devkit/architect": "^0.1602.11", - "@angular-devkit/build-angular": "^16.2.11", - "@angular-devkit/core": "^16.2.11", - "@angular-devkit/schematics": "16.2.11", - "@angular-eslint/eslint-plugin": "^16.2.0", - "@angular-eslint/eslint-plugin-template": "^16.2.0", - "@angular/cli": "^16.2.11", - "@angular/compiler-cli": "^16.2.12", - "@commitlint/cli": "^17.6.6", - "@commitlint/config-conventional": "^17.6.6", - "@commitlint/config-lerna-scopes": "^17.6.6", - "@commitlint/travis-cli": "^17.6.6", - "@compodoc/compodoc": "^1.1.19", - "@cypress/browserify-preprocessor": "^3.0.2", - "@electron/remote": "^2.0.8", - "@nrwl/angular": "15.9.4", - "@nrwl/cli": "15.9.4", - "@nrwl/cypress": "15.9.4", - "@nrwl/eslint-plugin-nx": "15.9.4", - "@nrwl/jest": "15.9.4", - "@nrwl/linter": "15.9.4", - "@nrwl/nest": "15.9.4", - "@nrwl/node": "15.9.4", - "@nrwl/nx-cloud": "16.5.2", - "@nrwl/tao": "15.9.4", - "@nrwl/workspace": "15.9.4", - "@nstudio/angular": "^15.0.3", - "@nstudio/electron": "^15.0.3", - "@nstudio/electron-angular": "^15.0.3", - "@nstudio/web": "^15.0.3", - "@nstudio/web-angular": "^15.0.3", - "@nstudio/xplat": "^15.0.3", - "@semantic-release/changelog": "^5.0.1", - "@semantic-release/git": "^9.0.0", - "@semantic-release/github": "^7.2.1", - "@semantic-release/npm": "^7.1.1", - "@types/jest": "^29.4.4", - "@types/jsdom": "^21.1.6", - "@types/webpack": "^5.28.5", - "@types/yargs": "^15.0.9", - "ajv-formats": "^2.1.1", - "cloc": "^2.7.0", - "codecov": "^3.8.3", - "codelyzer": "^6.0.1", - "commitizen": "^4.2.1", - "concurrently": "^5.3.0", - "conventional-changelog": "^3.1.23", - "conventional-changelog-cli": "^2.1.0", - "copy-webpack-plugin": "^9.0.1", - "cross-env": "^7.0.3", - "cspell": "^6.18.1", - "cypress": "^9.4.1", - "cypress-cucumber-preprocessor": "^4.3.1", - "cypress-file-upload": "^5.0.8", - "cz-conventional-changelog": "^3.3.0", - "electron": "28.1.0", - "electron-builder": "^24.6.4", - "envalid": "^6.0.2", - "esbuild": "^0.15.13", - "eslint-plugin-cypress": "2.13.4", - "fork-ts-checker-webpack-plugin": "^5.2.0", - "gulp-tag-version": "^1.3.1", - "husky": "^6.0.0", - "jest": "29.7.0", - "jest-environment-jsdom": "29.7.0", - "jest-jasmine2": "29.4.3", - "jest-preset-angular": "13.1.4", - "lerna": "^4.0.0", - "lerna-changelog": "^1.0.1", - "lighthouse": "^6.3.0", - "lint-staged": "^10.4.0", - "ng-packagr": "16.2.3", - "node-gyp": "^9.3.1", - "npm-run-all": "^4.1.5", - "nx": "15.9.4", - "nx-cloud": "^16.5.2", - "pkg": "^5.3.0", - "png-to-ico": "^2.1.8", - "prettier": "^2.8.4", - "prettier-tslint": "^0.4.2", - "pretty-quick": "^3.1.0", - "protractor": "^7.0.0", - "rimraf": "^3.0.2", - "semantic-release": "^17.4.2", - "simple-git": "^3.20.0", - "stylelint": "^15.10.1", - "ts-jest": "29.1.1", - "ts-loader": "^8.0.4", - "ts-node": "^10.9.1", - "tsconfig-paths": "^3.9.0", - "tslint": "^6.1.3", - "tslint-config-prettier": "^1.18.0", - "tslint-language-service": "^0.9.9", - "typedoc": "^0.23.24", - "typescript": "5.1.6", - "webpack": "^5.58.1", - "webpack-bundle-analyzer": "^4.4.2", - "webpack-cli": "^4.9.0", - "webpack-merge": "^5.8.0", - "webpack-node-externals": "^3.0.0" - }, - "overrides": { - "prebuild": { - "node-gyp": "$node-gyp" - }, - "iconv": { - "node-gyp": "9.3.1" - } - }, - "engines": { - "node": ">=16.20.1", - "yarn": ">=1.22.19" - }, - "prettier": { - "printWidth": 120, - "singleQuote": true, - "semi": true, - "useTabs": true, - "tabWidth": 4, - "arrowParens": "always", - "trailingComma": "none", - "quoteProps": "as-needed", - "trimTrailingWhitespace": true, - "overrides": [ - { - "files": "*.scss", - "options": { - "useTabs": false, - "tabWidth": 2 - } - }, - { - "files": "*.yml", - "options": { - "useTabs": false, - "tabWidth": 2 - } - } - ] - }, - "snyk": true, - "xplat": { - "prefix": "gauzy", - "framework": "angular" - } + "name": "ever-gauzy", + "version": "0.1.0", + "description": "Ever Gauzy - Business Management Platform (ERP/CRM/HRM)", + "license": "AGPL-3.0", + "homepage": "https://gauzy.co", + "repository": { + "type": "git", + "url": "https://github.com/ever-co/ever-gauzy.git" + }, + "bugs": { + "url": "https://github.com/ever-co/ever-gauzy/issues" + }, + "private": true, + "author": { + "name": "Ever Co. LTD", + "email": "ever@ever.co", + "url": "https://ever.co" + }, + "keywords": [], + "scripts": { + "prepare:husky": "npx husky install .husky", + "ng": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=12288 yarn nx", + "ng:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn nx", + "ng:docker": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn nx", + "ng:ci": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn nx", + "config": "yarn ts-node ./.scripts/configure.ts", + "config:dev": "yarn run config -- --environment=dev", + "config:prod": "yarn run config -- --environment=prod", + "start": "yarn build:package:all && yarn concurrently --raw --kill-others \"yarn start:api\" \"yarn start:gauzy\"", + "start:prod": "yarn build:package:all && yarn concurrently --raw --kill-others \"yarn start:api:prod\" \"yarn start:gauzy:prod\"", + "start:gauzy": "yarn run postinstall.web && yarn run config:dev && yarn ng serve gauzy --open", + "start:gauzy:forever": "yarn run config:dev && forever start node_modules/@angular/cli/bin/ng serve gauzy --disable-host-check --host 0.0.0.0", + "start:gauzy:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn build:package:all && yarn build:gauzy && yarn ts-node ./apps/gauzy/src/pm2bootstrap.ts", + "start:gauzy:prod": "yarn run config:prod && yarn ng serve gauzy --configuration production --disable-host-check --host 0.0.0.0 --prod", + "start:api": "yarn ng serve api", + "start:api:prod": "yarn ng:prod serve api --host 0.0.0.0 -c=production --prod", + "start:api:ci": "yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci serve api -c=production --prod", + "start:api:forever": "forever start node_modules/@angular/cli/bin/ng serve api --host 0.0.0.0", + "start:api:pm2": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn run build:api && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/pm2bootstrap.ts", + "start:api:core": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=4096 yarn --cwd ./packages/core start:api", + "migration:run": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:run", + "migration:revert": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:revert", + "migration:generate": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:generate", + "migration:create": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/migration.ts migration:create", + "migration:command": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core", + "seed": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed.ts", + "seed:ever": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-ever.ts", + "seed:all": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-all.ts", + "seed:jobs": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-jobs.ts", + "seed:module": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:dev && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed-module.ts --name", + "seed:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn build:package:all && yarn run config:prod && yarn ts-node -r tsconfig-paths/register --project apps/api/tsconfig.app.json ./apps/api/src/seed.ts", + "bootstrap": "yarn install && yarn lerna bootstrap", + "prebuild": "rimraf dist coverage", + "build": "yarn build:package:all && concurrently --raw \"yarn build:api\" \"yarn build:gauzy\"", + "build:lerna": "yarn lerna run --parallel build", + "build:prod": "yarn build:package:all && concurrently --raw \"yarn build:api:prod\" \"yarn build:gauzy:prod\"", + "build:gauzy": "yarn run postinstall.web && yarn run config:dev && yarn ng build gauzy", + "build:gauzy:prod": "yarn run config:prod && yarn ng:prod build gauzy -c=production --prod --verbose", + "build:gauzy:prod:docker": "yarn run config:prod && yarn ng:docker build gauzy -c=production --prod --verbose", + "build:gauzy:prod:ci": "yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci build gauzy -c=production --prod --verbose", + "build:api": "yarn ng build api", + "build:api:prod": "yarn ng:prod build api -c=production --prod", + "build:api:prod:docker": "yarn ng:docker build api -c=production --prod", + "build:api:prod:ci": "yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci build api -c=production --prod", + "bundle-report": "yarn run config:prod && yarn ng:prod build -c=production --stats-json && webpack-bundle-analyzer dist/apps/gauzy/stats.json", + "commit": "git-cz", + "commit:lint": "commitlint -E HUSKY_GIT_PARAMS", + "semantic-release": "semantic-release", + "test": "yarn run postinstall.web && yarn run config:dev && yarn ng test", + "lint": "yarn run config:dev && yarn ng lint && yarn ng lint", + "e2e": "yarn run postinstall.web && yarn run config:dev && yarn ng e2e --browser chrome", + "e2e:ci": "yarn run postinstall.web && yarn run config:prod && yarn --frozen-lockfile --cache-folder ~/.cache/yarn ng:ci e2e -c=production --prod --headless", + "affected:apps": "yarn nx affected:apps", + "affected:libs": "yarn nx affected:libs", + "affected:build": "yarn nx affected:build", + "affected:e2e": "yarn nx affected:e2e", + "affected:test": "yarn nx affected:test", + "affected:lint": "yarn nx affected:lint", + "affected:dep-graph": "yarn nx affected:dep-graph", + "affected": "yarn nx affected", + "format": "yarn nx format:write", + "format:write": "yarn nx format:write", + "format:check": "yarn nx format:check", + "update": "yarn ng update @nrwl/workspace", + "update:check": "yarn ng update", + "workspace-schematic": "yarn nx workspace-schematic", + "dep-graph": "yarn nx dep-graph", + "help": "yarn nx help", + "doc:build": "compodoc -p tsconfig.json -d dist/docs", + "doc:serve": "compodoc -s -d dist/docs", + "doc:build-serve": "compodoc -p tsconfig.json -d docs -s", + "postinstall.electron": "yarn electron-builder install-app-deps && yarn node tools/electron/postinstall", + "postinstall.web": "yarn node ./decorate-angular-cli.js && yarn npx ngcc --properties es2016 browser module main --first-only --create-ivy-entry-points && yarn node tools/web/postinstall", + "build:desktop": "cross-env NODE_ENV=production yarn run copy-files-i18n-desktop && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:desktop:prod && yarn run pack:desktop && yarn run generate:icons:desktop --environment=prod && yarn ng:prod build desktop --prod --base-href ./ && yarn run prepare:desktop && yarn ng:prod build desktop-api --prod && yarn ng:prod build api-desktop --prod --output-path=dist/apps/desktop/desktop-api && yarn ng:prod build desktop-ui --prod --base-href ./ && yarn run copy-files-desktop && yarn run copy-assets-gauzy", + "build:desktop:local": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && electron dist/apps/desktop", + "build:desktop:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/desktop", + "build:desktop:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop", + "build:desktop:mac": "yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop", + "build:desktop:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop", + "build:desktop:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop", + "build:desktop:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop", + "build:desktop:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop", + "build:desktop:mac:release": "yarn run build:desktop && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/desktop", + "prepare:desktop": "yarn run postinstall.electron && tsc -p apps/desktop/tsconfig.json", + "serve:desktop.target": "yarn ng serve desktop", + "serve:desktop": "wait-on http-get://localhost:4200/ && electron apps/desktop/src --serve", + "start:desktop": "yarn run prepare:desktop && npm-run-all -p serve.electron.gauzy-desktop.target serve.electron.gauzy-desktop", + "build:desktop:mac:quick": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop", + "build:desktop:local:quick": "yarn electron dist/apps/desktop --prod", + "build:desktop:windows:quick": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --windows --project dist/apps/desktop", + "build:sqlite:mac": "cd node_modules/sqlite3 && HOME=~/.electron-gyp node-pre-gyp rebuild --target=8.3.0 --arch=x64 --dist-url=https://electronjs.org/headers", + "build:sqlite:windows": "cd node_modules/sqlite3 && cross-env HOME=~/.electron-gyp node-pre-gyp rebuild --target=8.3.0 --arch=x64 --target_platform=win32 --dist-url=https://electronjs.org/headers", + "debug:desktop:app:mac": "lldb ./dist/apps/desktop-packages/mac/GauzyDesktop.app && run", + "start:desktop:ui": "yarn run postinstall.web && yarn ng serve desktop-ui", + "build:desktop:ui": "yarn run postinstall.web && yarn ng:prod build desktop-ui --prod --base-href ./", + "prepare:desktop:dev": "yarn run postinstall.electron && tsc -p apps/desktop/tsconfig.dev.json", + "start:api:desktop": "yarn ng serve api-desktop", + "deploy:desktop:mac": "npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish always --project dist/apps/desktop", + "build:package:auth": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/auth build", + "build:package:auth:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/auth build", + "build:package:core": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core build", + "build:package:core:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/core build", + "build:package:common": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common build", + "build:package:common:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common build", + "build:package:common-angular": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common-angular build", + "build:package:common-angular:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/common-angular build", + "build:package:contracts": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/contracts build", + "build:package:contracts:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/contracts build", + "build:package:config": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/config build", + "build:package:config:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/config build:prod", + "build:package:plugin": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugin build", + "build:package:plugin:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugin build", + "build:package:plugins": "yarn run build:package:plugin:integration-ai && yarn run build:package:plugin:integration-hubstaff && yarn run build:package:plugin:integration-upwork && yarn run build:package:plugin:integration-github && yarn run build:package:plugin:integration-jira", + "build:package:plugins:prod": "yarn run build:package:plugin:integration-ai:prod && yarn run build:package:plugin:integration-hubstaff:prod && yarn run build:package:plugin:integration-upwork:prod && yarn run build:package:plugin:integration-github:prod && yarn run build:package:plugin:integration-jira:prod", + "build:package:plugin:integration-ai": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-ai build", + "build:package:plugin:integration-ai:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-ai build", + "build:package:plugin:integration-hubstaff": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-hubstaff build", + "build:package:plugin:integration-hubstaff:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-hubstaff build", + "build:package:plugin:integration-upwork": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-upwork build", + "build:package:plugin:integration-upwork:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-upwork build", + "build:package:plugin:integration-github": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-github build", + "build:package:plugin:integration-github:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-github build", + "build:package:plugin:integration-jira": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-jira build", + "build:package:plugin:integration-jira:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-jira build", + "build:package:plugin:product-reviews": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/product-reviews build", + "build:package:plugin:product-reviews:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/product-reviews build", + "build:package:plugin:knowledge-base": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/knowledge-base build", + "build:package:plugin:knowledge-base:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/knowledge-base build", + "build:package:plugin:changelog": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/changelog build", + "build:package:plugin:changelog:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/changelog build", + "build:package:plugin:integration-wakatime": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-wakatime build", + "build:package:plugin:integration-wakatime:prod": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/plugins/integration-wakatime build", + "build:package:all": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:common-angular && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:product-reviews && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog && yarn build:package:desktop-libs && yarn build:package:plugin:integration-wakatime && yarn build:package:desktop-ui-lib", + "build:package:desktop-window": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-window build", + "build:package:desktop-libs": "yarn run build:package:desktop-window && cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-libs build", + "build:package:api": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog", + "build:package:api:prod": "yarn run build:package:contracts:prod && yarn run build:package:common:prod && yarn run build:package:config:prod && yarn run build:package:plugin:prod && yarn run build:package:plugins:prod && yarn run build:package:auth:prod && yarn run build:package:core:prod && yarn run build:package:plugin:knowledge-base:prod && yarn run build:package:plugin:changelog:prod", + "build:package:gauzy": "yarn run build:package:contracts && yarn run build:package:common && yarn run build:package:common-angular && yarn run build:package:config && yarn run build:package:plugin && yarn run build:package:plugins && yarn run build:package:auth && yarn run build:package:core && yarn run build:package:plugin:knowledge-base && yarn run build:package:plugin:changelog", + "build:package:desktop-ui-lib": "cross-env NODE_ENV=development NODE_OPTIONS=--max-old-space-size=7000 yarn --cwd ./packages/desktop-ui-lib build", + "copy-files-desktop": "copyfiles -f packages/core/src/**/*.gql dist/apps/desktop/data/", + "build:desktop-timer": "cross-env NODE_ENV=production yarn copy-files-i18n-desktop-timer && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:desktop-timer:prod && yarn run pack:desktop-timer && yarn run generate:icons:desktop-timer --environment=prod && yarn ng:prod build desktop-timer --prod --base-href ./ && yarn run prepare:desktop-timer && yarn ng:prod build api-desktop --prod --output-path=dist/apps/desktop-timer/desktop-api && yarn run copy-assets-gauzy-timer", + "prepare:desktop-timer": "yarn run postinstall.electron && tsc -p apps/desktop-timer/tsconfig.json", + "build:desktop-timer:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/desktop-timer", + "build:desktop-timer:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/desktop-timer", + "build:desktop-timer:mac": "yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/desktop-timer", + "build:desktop-timer:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop-timer", + "build:desktop-timer:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/desktop-timer", + "build:desktop-timer:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", + "build:desktop-timer:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/desktop-timer", + "build:desktop-timer:mac:release": "yarn run build:desktop-timer && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/desktop-timer", + "copy-assets-gauzy": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop/data/sound/", + "copy-assets-gauzy-timer": "copyfiles -f apps/desktop/src/assets/snapshot-sound.wav dist/apps/desktop-timer/data/sound/", + "config:electron": "yarn ts-node ./.scripts/electron.env.ts", + "config:server:prod": "yarn run config:electron -- --environment=prod --desktop=server", + "config:desktop:prod": "yarn run config:electron -- --environment=prod --desktop=desktop", + "config:desktop-timer:prod": "yarn run config:electron -- --environment=prod --desktop=desktop-timer", + "prepare:gauzy-server": "yarn run postinstall.electron && tsc -p apps/server/tsconfig.json", + "build:gauzy-server": "cross-env NODE_ENV=production yarn run copy-files-i18n-server && yarn run postinstall.electron && yarn build:package:all && yarn run config:prod && yarn run config:server:prod && yarn run pack:server && yarn run generate:icons:server --environment=prod && yarn ng:prod build gauzy-server --prod --base-href ./ && yarn run prepare:gauzy-server && yarn ng:prod build gauzy-server-ui --prod --base-href ./ && yarn ng:prod build gauzy-server-api --prod && yarn run copy-files-gauzy-server", + "copy-files-gauzy-server": "copyfiles -f packages/core/src/**/*.gql dist/apps/gauzy-server/data/", + "build:gauzy-server:windows": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --project dist/apps/gauzy-server", + "build:gauzy-server:linux": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --project dist/apps/gauzy-server", + "build:gauzy-server:mac": "yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --project dist/apps/gauzy-server", + "build:gauzy-server:windows:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/gauzy-server", + "build:gauzy-server:windows:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --windows --publish=always --project dist/apps/gauzy-server", + "build:gauzy-server:linux:release": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=7000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/gauzy-server", + "build:gauzy-server:linux:release:gh": "cross-env NODE_ENV=production NODE_OPTIONS=--max-old-space-size=30000 yarn run config:prod && yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --linux --publish=always --project dist/apps/gauzy-server", + "build:gauzy-server:mac:release": "yarn run build:gauzy-server && npm config set cache .cache && yarn electron-builder -c.electronVersion=28.1.0 build --mac --publish=always --project dist/apps/gauzy-server", + "quick:build:gauzy-server": "yarn electron-builder -c.electronVersion=28.1.0 -c.extraMetadata.author.name=Ever build --mac --project dist/apps/gauzy-server", + "copy-files-i18n-desktop-timer": "yarn run download:translations --desktop=desktop-timer", + "copy-files-i18n-desktop": "yarn run download:translations --desktop=desktop", + "copy-files-i18n-server": "yarn run download:translations --desktop=server", + "generate:icons": "yarn ts-node .scripts/icon-utils/icon-factory.ts", + "generate:icons:desktop-timer": "yarn run generate:icons --desktop=desktop-timer", + "generate:icons:desktop": "yarn run generate:icons --desktop=desktop", + "generate:icons:server": "yarn run generate:icons --desktop=server", + "pack": "yarn ts-node .scripts/electron-package-utils/package-util.ts", + "pack:desktop-timer": "yarn run pack --desktop=desktop-timer", + "pack:desktop": "yarn run pack --desktop=desktop", + "pack:server": "yarn run pack --desktop=server", + "download:translations": "yarn ts-node .scripts/translation/translation-util.ts" + }, + "config": { + "commitizen": { + "path": "cz-conventional-changelog" + } + }, + "commitlint": { + "extends": [ + "@commitlint/config-conventional" + ] + }, + "husky": { + "hooks": { + "commit-msg": "commitlint -E HUSKY_GIT_PARAMS", + "pre-commit": "pretty-quick --no-verify --staged" + } + }, + "lint-staged": {}, + "release": { + "verifyConditions": [ + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git", + "@semantic-release/github" + ], + "prepare": [ + "@semantic-release/changelog", + "@semantic-release/npm", + "@semantic-release/git" + ], + "publish": [ + "@semantic-release/github" + ], + "generateNotes": { + "preset": "angular" + }, + "npmPublish": false + }, + "workspaces": { + "packages": [ + "libs/*", + "apps/*", + "tools", + "packages/*", + "packages/plugins/*" + ], + "nohoist": [ + "**/@types/jasmine", + "**/@types/jasminewd2", + "**/@angular*/**", + "**/@ngtools/**" + ] + }, + "resolutions": { + "@angular-devkit/architect": "^0.1602.11", + "@angular-devkit/build-angular": "^16.2.11", + "@angular-devkit/core": "^16.2.11", + "rxjs": "^7.4.0", + "autoprefixer": "10.4.14" + }, + "dependencies": { + "@angular/animations": "^16.2.12", + "@angular/cdk": "^16.2.12", + "@angular/common": "^16.2.12", + "@angular/compiler": "^16.2.12", + "@angular/core": "^16.2.12", + "@angular/forms": "^16.2.12", + "@angular/language-service": "^16.2.12", + "@angular/material": "^16.2.12", + "@angular/platform-browser": "^16.2.12", + "@angular/platform-browser-dynamic": "^16.2.12", + "@angular/router": "^16.2.12", + "@angular/service-worker": "^16.2.12", + "@nebular/auth": "^12.0.0", + "@nebular/bootstrap": "^9.1.0-rc.6", + "@nebular/eva-icons": "^12.0.0", + "@nebular/security": "^12.0.0", + "@nebular/theme": "^12.0.0", + "@ng-select/ng-select": "^11.2.0", + "angular2-smart-table": "^3.2.0", + "autoprefixer": "10.4.14", + "bcrypt": "^5.1.0", + "dotenv": "^16.0.3", + "ffi-napi": "^4.0.3", + "iconv": "^3.0.1", + "jsdom": "^23.0.1", + "lodash-es": "^4.17.21", + "parse5": "^7.1.2", + "rxjs": "^7.4.0", + "unleash": "^2.0.2", + "yargs": "^17.5.0" + }, + "devDependencies": { + "@angular-devkit/architect": "^0.1602.11", + "@angular-devkit/build-angular": "^16.2.11", + "@angular-devkit/core": "^16.2.11", + "@angular-devkit/schematics": "16.2.11", + "@angular-eslint/eslint-plugin": "^16.2.0", + "@angular-eslint/eslint-plugin-template": "^16.2.0", + "@angular/cli": "^16.2.11", + "@angular/compiler-cli": "^16.2.12", + "@commitlint/cli": "^17.6.6", + "@commitlint/config-conventional": "^17.6.6", + "@commitlint/config-lerna-scopes": "^17.6.6", + "@commitlint/travis-cli": "^17.6.6", + "@compodoc/compodoc": "^1.1.19", + "@cypress/browserify-preprocessor": "^3.0.2", + "@electron/remote": "^2.0.8", + "@nrwl/angular": "15.9.4", + "@nrwl/cli": "15.9.4", + "@nrwl/cypress": "15.9.4", + "@nrwl/eslint-plugin-nx": "15.9.4", + "@nrwl/jest": "15.9.4", + "@nrwl/linter": "15.9.4", + "@nrwl/nest": "15.9.4", + "@nrwl/node": "15.9.4", + "@nrwl/nx-cloud": "16.5.2", + "@nrwl/tao": "15.9.4", + "@nrwl/workspace": "15.9.4", + "@nstudio/angular": "^15.0.3", + "@nstudio/electron": "^15.0.3", + "@nstudio/electron-angular": "^15.0.3", + "@nstudio/web": "^15.0.3", + "@nstudio/web-angular": "^15.0.3", + "@nstudio/xplat": "^15.0.3", + "@semantic-release/changelog": "^5.0.1", + "@semantic-release/git": "^9.0.0", + "@semantic-release/github": "^7.2.1", + "@semantic-release/npm": "^7.1.1", + "@types/jest": "^29.4.4", + "@types/jsdom": "^21.1.6", + "@types/webpack": "^5.28.5", + "@types/yargs": "^15.0.9", + "ajv-formats": "^2.1.1", + "cloc": "^2.7.0", + "codecov": "^3.8.3", + "codelyzer": "^6.0.1", + "commitizen": "^4.2.1", + "concurrently": "^5.3.0", + "conventional-changelog": "^3.1.23", + "conventional-changelog-cli": "^2.1.0", + "copy-webpack-plugin": "^9.0.1", + "cross-env": "^7.0.3", + "cspell": "^6.18.1", + "cypress": "^9.4.1", + "cypress-cucumber-preprocessor": "^4.3.1", + "cypress-file-upload": "^5.0.8", + "cz-conventional-changelog": "^3.3.0", + "electron": "28.1.0", + "electron-builder": "^24.6.4", + "envalid": "^6.0.2", + "esbuild": "^0.15.13", + "eslint-plugin-cypress": "2.13.4", + "fork-ts-checker-webpack-plugin": "^5.2.0", + "gulp-tag-version": "^1.3.1", + "husky": "^6.0.0", + "jest": "29.7.0", + "jest-environment-jsdom": "29.7.0", + "jest-jasmine2": "29.4.3", + "jest-preset-angular": "13.1.4", + "lerna": "^4.0.0", + "lerna-changelog": "^1.0.1", + "lighthouse": "^6.3.0", + "lint-staged": "^10.4.0", + "ng-packagr": "16.2.3", + "node-gyp": "^9.3.1", + "npm-run-all": "^4.1.5", + "nx": "15.9.4", + "nx-cloud": "^16.5.2", + "pkg": "^5.3.0", + "png-to-ico": "^2.1.8", + "prettier": "^2.8.4", + "prettier-tslint": "^0.4.2", + "pretty-quick": "^3.1.0", + "protractor": "^7.0.0", + "rimraf": "^3.0.2", + "semantic-release": "^17.4.2", + "simple-git": "^3.20.0", + "stylelint": "^15.10.1", + "ts-jest": "29.1.1", + "ts-loader": "^8.0.4", + "ts-node": "^10.9.1", + "tsconfig-paths": "^3.9.0", + "tslint": "^6.1.3", + "tslint-config-prettier": "^1.18.0", + "tslint-language-service": "^0.9.9", + "typedoc": "^0.23.24", + "typescript": "5.1.6", + "webpack": "^5.58.1", + "webpack-bundle-analyzer": "^4.4.2", + "webpack-cli": "^4.9.0", + "webpack-merge": "^5.8.0", + "webpack-node-externals": "^3.0.0" + }, + "overrides": { + "prebuild": { + "node-gyp": "$node-gyp" + }, + "iconv": { + "node-gyp": "9.3.1" + } + }, + "engines": { + "node": ">=16.20.1", + "yarn": ">=1.22.19" + }, + "prettier": { + "printWidth": 120, + "singleQuote": true, + "semi": true, + "useTabs": true, + "tabWidth": 4, + "arrowParens": "always", + "trailingComma": "none", + "quoteProps": "as-needed", + "trimTrailingWhitespace": true, + "overrides": [ + { + "files": "*.scss", + "options": { + "useTabs": false, + "tabWidth": 2 + } + }, + { + "files": "*.yml", + "options": { + "useTabs": false, + "tabWidth": 2 + } + } + ] + }, + "snyk": true, + "xplat": { + "prefix": "gauzy", + "framework": "angular" + } } diff --git a/packages/core/src/core/crud/pagination-params.ts b/packages/core/src/core/crud/pagination-params.ts index 685e6614707..fb4ded005a9 100644 --- a/packages/core/src/core/crud/pagination-params.ts +++ b/packages/core/src/core/crud/pagination-params.ts @@ -4,10 +4,11 @@ import { ApiProperty, ApiPropertyOptional } from '@nestjs/swagger'; import { FindOptionsOrder, FindOptionsRelations, FindOptionsSelect, FindOptionsWhere } from 'typeorm'; -import { Transform, TransformFnParams, Type } from 'class-transformer'; +import { Transform, TransformFnParams, Type, plainToClass } from 'class-transformer'; import { IsNotEmpty, IsOptional, Max, Min, ValidateNested } from 'class-validator'; -import { isClassInstance, isObject, parseToBoolean } from '@gauzy/common'; +import { parseToBoolean } from '@gauzy/common'; import { TenantOrganizationBaseDTO } from './../../core/dto'; +import { SimpleObjectLiteral, convertNativeParameters, parseObject } from './pagination.helper'; /** * Specifies what columns should be retrieved. @@ -45,6 +46,7 @@ export class OptionParams extends OptionsRelations { @IsNotEmpty() @ValidateNested({ each: true }) @Type(() => TenantOrganizationBaseDTO) + @Transform(({ value }: TransformFnParams) => value ? escapeQueryWithParameters(value) : {}) readonly where: FindOptionsWhere; /** @@ -81,22 +83,14 @@ export class PaginationParams extends OptionParams { } /** - * Parse object to specific type - * - * @param source - * @returns + * Function to escape query parameters and convert to DTO class. + * @param nativeParameters - The original query parameters. + * @returns {TenantOrganizationBaseDTO} - The escaped and converted query parameters as a DTO instance. */ -export function parseObject(source: Object, callback: Function) { - if (isObject(source)) { - for (const key in source) { - if (isObject(source[key])) { - if (!isClassInstance(source[key])) { - parseObject(source[key], callback); - } - } else { - Object.assign(source, { [key]: callback(source[key]) }) - } - } - } - return source; +export function escapeQueryWithParameters(nativeParameters: SimpleObjectLiteral): TenantOrganizationBaseDTO { + // Convert native parameters based on the database connection type + const builtParameters: SimpleObjectLiteral = convertNativeParameters(nativeParameters); + + // Convert to DTO class using class-transformer's plainToClass + return plainToClass(TenantOrganizationBaseDTO, builtParameters, { enableImplicitConversion: true }); } diff --git a/packages/core/src/core/crud/pagination.helper.ts b/packages/core/src/core/crud/pagination.helper.ts new file mode 100644 index 00000000000..a7f4e1ae515 --- /dev/null +++ b/packages/core/src/core/crud/pagination.helper.ts @@ -0,0 +1,60 @@ +import { isClassInstance, isObject } from "@gauzy/common"; + +/** + * Interface of the simple literal object with any string keys. + */ +export interface SimpleObjectLiteral { + [key: string]: any; +} + +/** + * Parses the given value and converts it to a boolean using JSON.parse. + * + * @param value - The value to be parsed. + * @returns {boolean} - The boolean representation of the parsed value. + */ +export const parseBool = (value: any): boolean => Boolean(JSON.parse(value)); + +/** + * Converts native parameters based on the database connection type. + * + * @param parameters - The parameters to be converted. + * @returns {any} - The converted parameters based on the database connection type. + */ +export const convertNativeParameters = (parameters: any): any => { + try { + // Mapping boolean values to their numeric representation + if (typeof parameters === "object" && parameters !== null) { + // Recursively convert nested objects + return Object.keys(parameters).reduce((acc, key) => { + acc[key] = convertNativeParameters(parameters[key]); + return acc; + }, {} as SimpleObjectLiteral); + } else { + return parseBool(parameters); + } + } catch (error) { + return parameters; + } +}; + +/** + * Parse object to specific type + * + * @param source + * @returns + */ +export function parseObject(source: Object, callback: Function) { + if (isObject(source)) { + for (const key in source) { + if (isObject(source[key])) { + if (!isClassInstance(source[key])) { + parseObject(source[key], callback); + } + } else { + Object.assign(source, { [key]: callback(source[key]) }) + } + } + } + return source; +} diff --git a/packages/core/src/employee/commands/get-employee-job-statistics.command.ts b/packages/core/src/employee/commands/get-employee-job-statistics.command.ts index a16421098ba..06af227e9a6 100644 --- a/packages/core/src/employee/commands/get-employee-job-statistics.command.ts +++ b/packages/core/src/employee/commands/get-employee-job-statistics.command.ts @@ -6,6 +6,6 @@ export class GetEmployeeJobStatisticsCommand implements ICommand { static readonly type = '[EmployeeJobStatistics] Get'; constructor( - public readonly request: PaginationParams - ) {} + public readonly options: PaginationParams + ) { } } diff --git a/packages/core/src/employee/commands/handlers/get-employee-job-statistics.handler.ts b/packages/core/src/employee/commands/handlers/get-employee-job-statistics.handler.ts index c6ab01b40b9..e3e367975dd 100644 --- a/packages/core/src/employee/commands/handlers/get-employee-job-statistics.handler.ts +++ b/packages/core/src/employee/commands/handlers/get-employee-job-statistics.handler.ts @@ -1,35 +1,50 @@ import { CommandHandler, ICommandHandler } from '@nestjs/cqrs'; import { GauzyAIService } from '@gauzy/integration-ai'; import { IEmployee, IPagination } from '@gauzy/contracts'; -import { indexBy } from 'underscore'; import { EmployeeService } from '../../employee.service'; import { GetEmployeeJobStatisticsCommand } from '../get-employee-job-statistics.command'; @CommandHandler(GetEmployeeJobStatisticsCommand) -export class GetEmployeeJobStatisticsHandler - implements ICommandHandler { +export class GetEmployeeJobStatisticsHandler implements ICommandHandler { + /** + * + * @param employeeService + * @param gauzyAIService + */ constructor( private readonly employeeService: EmployeeService, private readonly gauzyAIService: GauzyAIService ) { } + /** + * Executes the GetEmployeeJobStatisticsCommand to fetch paginated employee data + * and augment it with additional statistics. + * + * @param command - The command containing options for pagination. + * @returns A Promise resolving to an IPagination with augmented data. + */ public async execute(command: GetEmployeeJobStatisticsCommand): Promise> { - const { request } = command; + const { options } = command; - let { items, total } = await this.employeeService.paginate(request); - const employeesStatistics = await this.gauzyAIService.getEmployeesStatistics(); - const employeesStatisticsById = indexBy( - employeesStatistics, - 'employeeId' + // Use Promise.all for concurrent requests + const [paginationResult, employeesStatistics] = await Promise.all([ + this.employeeService.paginate(options), + this.gauzyAIService.getEmployeesStatistics() + ]); + + let { items, total } = paginationResult; + + // Create a map for faster lookup + const employeesStatisticsById = new Map( + employeesStatistics.map((statistic: any) => [statistic.employeeId, statistic]) ); - items = items.map((employee) => { - const employeesStatistic = employeesStatisticsById[employee.id]; - return { - ...employee, - ...employeesStatistic - }; - }); + // Combine mappings into a single map function + items = items.map((employee: IEmployee) => ({ + ...employee, + ...employeesStatisticsById.get(employee.id) || {} // Use empty object if not found + })); + return { items, total }; } } diff --git a/packages/core/src/employee/employee.controller.ts b/packages/core/src/employee/employee.controller.ts index beaf695a53a..4c39ce0d440 100644 --- a/packages/core/src/employee/employee.controller.ts +++ b/packages/core/src/employee/employee.controller.ts @@ -211,9 +211,9 @@ export class EmployeeController extends CrudController { @Get('pagination') @UsePipes(new ValidationPipe({ transform: true })) async pagination( - @Query() options: PaginationParams + @Query() params: PaginationParams ): Promise> { - return await this.employeeService.pagination(options); + return await this.employeeService.pagination(params); } /** diff --git a/packages/core/src/employee/employee.service.ts b/packages/core/src/employee/employee.service.ts index a0a2ede635b..31b0bf4ce6a 100644 --- a/packages/core/src/employee/employee.service.ts +++ b/packages/core/src/employee/employee.service.ts @@ -216,15 +216,13 @@ export class EmployeeService extends TenantAwareCrudService { ); // Additional conditions based on the provided 'where' object if (isNotEmpty(where)) { - const parseBool = (value: any) => Boolean(JSON.parse(value)); - // Apply conditions for specific fields in the Employee entity qb.andWhere( new Brackets((web: WhereExpressionBuilder) => { const fields = ['isActive', 'isArchived', 'isTrackingEnabled', 'allowScreenshotCapture']; fields.forEach((key: string) => { if (key in where) { - web.andWhere(p(`${qb.alias}.${key} = :${key}`), { [key]: parseBool(where[key]) }); + web.andWhere(p(`${qb.alias}.${key} = :${key}`), { [key]: where[key] }); } }); }) diff --git a/packages/desktop-libs/src/lib/config/local-server-update-config.ts b/packages/desktop-libs/src/lib/config/local-server-update-config.ts index 913828dbe06..4ee584dcae2 100644 --- a/packages/desktop-libs/src/lib/config/local-server-update-config.ts +++ b/packages/desktop-libs/src/lib/config/local-server-update-config.ts @@ -1,4 +1,5 @@ export const LOCAL_SERVER_UPDATE_CONFIG = { FOLDER_PATH: '/', - PORT: 11999 + PORT: 11999, + TEST_SSL_PORT: 11998 }; diff --git a/packages/desktop-libs/src/lib/config/server-config.ts b/packages/desktop-libs/src/lib/config/server-config.ts index 556127e9b06..7c8883970f9 100644 --- a/packages/desktop-libs/src/lib/config/server-config.ts +++ b/packages/desktop-libs/src/lib/config/server-config.ts @@ -27,9 +27,7 @@ export class ServerConfig implements IServerConfig { const regex = /api:\s*['"]((https?:\/\/[^'"]+))['"]/g; const match = regex.exec(fileContent); // Replace all occurrences of the URL with the new one - return match - ? fileContent.replace(regex, `api: '${newUrl}'`) - : this._initialConfig(newUrl, fileContent); + return match ? fileContent.replace(regex, `api: '${newUrl}'`) : this._initialConfig(newUrl, fileContent); } private _removeDuplicates(text: string): string { @@ -37,13 +35,10 @@ export class ServerConfig implements IServerConfig { const scriptRegex = /(