Skip to content

Commit

Permalink
refactor: deprecate invokers - auto proxying apis - strict types (jan…
Browse files Browse the repository at this point in the history
…hq#924)

* refactor: deprecate invokers

* refactor: define routes and auto proxying routes

* refactor: declare types for APIs, avoid making dynamic calls to any functions from the web

* chore: deprecate route handling from preload script

* refactor: deprecate unused apis
  • Loading branch information
louis-jan authored Dec 11, 2023
1 parent df97714 commit c4d8def
Show file tree
Hide file tree
Showing 23 changed files with 337 additions and 548 deletions.
100 changes: 100 additions & 0 deletions core/src/api/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
/**
* App Route APIs
* @description Enum of all the routes exposed by the app
*/
export enum AppRoute {
setNativeThemeLight = 'setNativeThemeLight',
setNativeThemeDark = 'setNativeThemeDark',
setNativeThemeSystem = 'setNativeThemeSystem',
appDataPath = 'appDataPath',
appVersion = 'appVersion',
getResourcePath = 'getResourcePath',
openExternalUrl = 'openExternalUrl',
openAppDirectory = 'openAppDirectory',
openFileExplore = 'openFileExplorer',
relaunch = 'relaunch',
}

export enum AppEvent {
onAppUpdateDownloadUpdate = 'onAppUpdateDownloadUpdate',
onAppUpdateDownloadError = 'onAppUpdateDownloadError',
onAppUpdateDownloadSuccess = 'onAppUpdateDownloadSuccess',
}

export enum DownloadRoute {
abortDownload = 'abortDownload',
downloadFile = 'downloadFile',
pauseDownload = 'pauseDownload',
resumeDownload = 'resumeDownload',
}

export enum DownloadEvent {
onFileDownloadUpdate = 'onFileDownloadUpdate',
onFileDownloadError = 'onFileDownloadError',
onFileDownloadSuccess = 'onFileDownloadSuccess',
}

export enum ExtensionRoute {
baseExtensions = 'baseExtensions',
getActiveExtensions = 'getActiveExtensions',
installExtension = 'installExtension',
invokeExtensionFunc = 'invokeExtensionFunc',
updateExtension = 'updateExtension',
uninstallExtension = 'uninstallExtension',
}
export enum FileSystemRoute {
appendFile = 'appendFile',
copyFile = 'copyFile',
deleteFile = 'deleteFile',
exists = 'exists',
getResourcePath = 'getResourcePath',
getUserSpace = 'getUserSpace',
isDirectory = 'isDirectory',
listFiles = 'listFiles',
mkdir = 'mkdir',
readFile = 'readFile',
readLineByLine = 'readLineByLine',
rmdir = 'rmdir',
writeFile = 'writeFile',
}

export type ApiFunction = (...args: any[]) => any

export type AppRouteFunctions = {
[K in AppRoute]: ApiFunction
}

export type AppEventFunctions = {
[K in AppEvent]: ApiFunction
}

export type DownloadRouteFunctions = {
[K in DownloadRoute]: ApiFunction
}

export type DownloadEventFunctions = {
[K in DownloadEvent]: ApiFunction
}

export type ExtensionRouteFunctions = {
[K in ExtensionRoute]: ApiFunction
}

export type FileSystemRouteFunctions = {
[K in FileSystemRoute]: ApiFunction
}

export type APIFunctions = AppRouteFunctions &
AppEventFunctions &
DownloadRouteFunctions &
DownloadEventFunctions &
ExtensionRouteFunctions &
FileSystemRouteFunctions

export const APIRoutes = [
...Object.values(AppRoute),
...Object.values(DownloadRoute),
...Object.values(ExtensionRoute),
...Object.values(FileSystemRoute),
]
export const APIEvents = [...Object.values(AppEvent), ...Object.values(DownloadEvent)]
8 changes: 0 additions & 8 deletions core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,13 +30,6 @@ const downloadFile: (url: string, fileName: string) => Promise<any> = (url, file
const abortDownload: (fileName: string) => Promise<any> = (fileName) =>
global.core.api?.abortDownload(fileName)

/**
* Retrieves the path to the app data directory using the `coreAPI` object.
* If the `coreAPI` object is not available, the function returns `undefined`.
* @returns A Promise that resolves with the path to the app data directory, or `undefined` if the `coreAPI` object is not available.
*/
const appDataPath: () => Promise<any> = () => global.core.api?.appDataPath()

/**
* Gets the user space path.
* @returns {Promise<any>} A Promise that resolves with the user space path.
Expand Down Expand Up @@ -70,7 +63,6 @@ export {
executeOnMain,
downloadFile,
abortDownload,
appDataPath,
getUserSpace,
openFileExplorer,
getResourcePath,
Expand Down
17 changes: 11 additions & 6 deletions core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,34 +2,39 @@
* Export all types.
* @module
*/
export * from "./types/index";
export * from './types/index'

/**
* Export all routes
*/
export * from './api'

/**
* Export Core module
* @module
*/
export * from "./core";
export * from './core'

/**
* Export Event module.
* @module
*/
export * from "./events";
export * from './events'

/**
* Export Filesystem module.
* @module
*/
export * from "./fs";
export * from './fs'

/**
* Export Extension module.
* @module
*/
export * from "./extension";
export * from './extension'

/**
* Export all base extensions.
* @module
*/
export * from "./extensions/index";
export * from './extensions/index'
45 changes: 32 additions & 13 deletions electron/handlers/app.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,43 @@
import { app, ipcMain, shell } from 'electron'
import { app, ipcMain, shell, nativeTheme } from 'electron'
import { ModuleManager } from './../managers/module'
import { join } from 'path'
import { ExtensionManager } from './../managers/extension'
import { WindowManager } from './../managers/window'
import { userSpacePath } from './../utils/path'
import { AppRoute } from '@janhq/core'
import { getResourcePath } from './../utils/path'

export function handleAppIPCs() {
/**
* Retrieves the path to the app data directory using the `coreAPI` object.
* If the `coreAPI` object is not available, the function returns `undefined`.
* @returns A Promise that resolves with the path to the app data directory, or `undefined` if the `coreAPI` object is not available.
* Handles the "setNativeThemeLight" IPC message by setting the native theme source to "light".
* This will change the appearance of the app to the light theme.
*/
ipcMain.handle('appDataPath', async (_event) => {
return app.getPath('userData')
ipcMain.handle(AppRoute.setNativeThemeLight, () => {
nativeTheme.themeSource = 'light'
})

/**
* Handles the "setNativeThemeDark" IPC message by setting the native theme source to "dark".
* This will change the appearance of the app to the dark theme.
*/
ipcMain.handle(AppRoute.setNativeThemeDark, () => {
nativeTheme.themeSource = 'dark'
})

/**
* Handles the "setNativeThemeSystem" IPC message by setting the native theme source to "system".
* This will change the appearance of the app to match the system's current theme.
*/
ipcMain.handle(AppRoute.setNativeThemeSystem, () => {
nativeTheme.themeSource = 'system'
})

/**
* Returns the version of the app.
* @param _event - The IPC event object.
* @returns The version of the app.
*/
ipcMain.handle('appVersion', async (_event) => {
ipcMain.handle(AppRoute.appVersion, async (_event) => {
return app.getVersion()
})

Expand All @@ -29,16 +46,20 @@ export function handleAppIPCs() {
* The `shell.openPath` method is used to open the directory in the user's default file explorer.
* @param _event - The IPC event object.
*/
ipcMain.handle('openAppDirectory', async (_event) => {
ipcMain.handle(AppRoute.openAppDirectory, async (_event) => {
shell.openPath(userSpacePath)
})

ipcMain.handle(AppRoute.getResourcePath, async (_event) => {
return getResourcePath()
})

/**
* Opens a URL in the user's default browser.
* @param _event - The IPC event object.
* @param url - The URL to open.
*/
ipcMain.handle('openExternalUrl', async (_event, url) => {
ipcMain.handle(AppRoute.openExternalUrl, async (_event, url) => {
shell.openExternal(url)
})

Expand All @@ -47,7 +68,7 @@ export function handleAppIPCs() {
* @param _event - The IPC event object.
* @param url - The URL to reload.
*/
ipcMain.handle('relaunch', async (_event, url) => {
ipcMain.handle(AppRoute.relaunch, async (_event, url) => {
ModuleManager.instance.clearImportedModules()

if (app.isPackaged) {
Expand All @@ -56,9 +77,7 @@ export function handleAppIPCs() {
} else {
for (const modulePath in ModuleManager.instance.requiredModules) {
delete require.cache[
require.resolve(
join(userSpacePath, 'extensions', modulePath)
)
require.resolve(join(userSpacePath, 'extensions', modulePath))
]
}
ExtensionManager.instance.setupExtensions()
Expand Down
22 changes: 9 additions & 13 deletions electron/handlers/download.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { resolve, join } from 'path'
import { WindowManager } from './../managers/window'
import request from 'request'
import { createWriteStream } from 'fs'
import { getResourcePath } from './../utils/path'
import { DownloadEvent, DownloadRoute } from '@janhq/core'
const progress = require('request-progress')

export function handleDownloaderIPCs() {
Expand All @@ -13,7 +13,7 @@ export function handleDownloaderIPCs() {
* @param _event - The IPC event object.
* @param fileName - The name of the file being downloaded.
*/
ipcMain.handle('pauseDownload', async (_event, fileName) => {
ipcMain.handle(DownloadRoute.pauseDownload, async (_event, fileName) => {
DownloadManager.instance.networkRequests[fileName]?.pause()
})

Expand All @@ -22,7 +22,7 @@ export function handleDownloaderIPCs() {
* @param _event - The IPC event object.
* @param fileName - The name of the file being downloaded.
*/
ipcMain.handle('resumeDownload', async (_event, fileName) => {
ipcMain.handle(DownloadRoute.resumeDownload, async (_event, fileName) => {
DownloadManager.instance.networkRequests[fileName]?.resume()
})

Expand All @@ -32,31 +32,27 @@ export function handleDownloaderIPCs() {
* @param _event - The IPC event object.
* @param fileName - The name of the file being downloaded.
*/
ipcMain.handle('abortDownload', async (_event, fileName) => {
ipcMain.handle(DownloadRoute.abortDownload, async (_event, fileName) => {
const rq = DownloadManager.instance.networkRequests[fileName]
DownloadManager.instance.networkRequests[fileName] = undefined
rq?.abort()
})

ipcMain.handle('getResourcePath', async (_event) => {
return getResourcePath()
})

/**
* Downloads a file from a given URL.
* @param _event - The IPC event object.
* @param url - The URL to download the file from.
* @param fileName - The name to give the downloaded file.
*/
ipcMain.handle('downloadFile', async (_event, url, fileName) => {
ipcMain.handle(DownloadRoute.downloadFile, async (_event, url, fileName) => {
const userDataPath = join(app.getPath('home'), 'jan')
const destination = resolve(userDataPath, fileName)
const rq = request(url)

progress(rq, {})
.on('progress', function (state: any) {
WindowManager?.instance.currentWindow?.webContents.send(
'FILE_DOWNLOAD_UPDATE',
DownloadEvent.onFileDownloadUpdate,
{
...state,
fileName,
Expand All @@ -65,7 +61,7 @@ export function handleDownloaderIPCs() {
})
.on('error', function (err: Error) {
WindowManager?.instance.currentWindow?.webContents.send(
'FILE_DOWNLOAD_ERROR',
DownloadEvent.onFileDownloadError,
{
fileName,
err,
Expand All @@ -75,15 +71,15 @@ export function handleDownloaderIPCs() {
.on('end', function () {
if (DownloadManager.instance.networkRequests[fileName]) {
WindowManager?.instance.currentWindow?.webContents.send(
'FILE_DOWNLOAD_COMPLETE',
DownloadEvent.onFileDownloadSuccess,
{
fileName,
}
)
DownloadManager.instance.setRequest(fileName, undefined)
} else {
WindowManager?.instance.currentWindow?.webContents.send(
'FILE_DOWNLOAD_ERROR',
DownloadEvent.onFileDownloadError,
{
fileName,
err: 'Download cancelled',
Expand Down
Loading

0 comments on commit c4d8def

Please sign in to comment.