diff --git a/.gitignore b/.gitignore index 0b6f98465..d3b50445e 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,5 @@ extensions/*-extension/bin/vulkaninfo # Turborepo .turbo +electron/test-data +electron/test-results diff --git a/core/src/node/api/processors/app.ts b/core/src/node/api/processors/app.ts index c98060da4..15460ba56 100644 --- a/core/src/node/api/processors/app.ts +++ b/core/src/node/api/processors/app.ts @@ -77,8 +77,8 @@ export class App implements Processor { port: args?.port, isCorsEnabled: args?.isCorsEnabled, isVerboseEnabled: args?.isVerboseEnabled, - schemaPath: join(await appResourcePath(), 'docs', 'openapi', 'jan.yaml'), - baseDir: join(await appResourcePath(), 'docs', 'openapi'), + schemaPath: join(appResourcePath(), 'docs', 'openapi', 'jan.yaml'), + baseDir: join(appResourcePath(), 'docs', 'openapi'), prefix: args?.prefix, }) } diff --git a/core/src/node/api/processors/extension.ts b/core/src/node/api/processors/extension.ts index df5d2d945..c8637d004 100644 --- a/core/src/node/api/processors/extension.ts +++ b/core/src/node/api/processors/extension.ts @@ -42,7 +42,7 @@ export class Extension implements Processor { * @returns An array of paths to the base extensions. */ async baseExtensions() { - const baseExtensionPath = join(await appResourcePath(), 'pre-install') + const baseExtensionPath = join(appResourcePath(), 'pre-install') return readdirSync(baseExtensionPath) .filter((file) => extname(file) === '.tgz') .map((file) => join(baseExtensionPath, file)) diff --git a/core/src/node/helper/config.ts b/core/src/node/helper/config.ts index 1a341a625..0d14280cc 100644 --- a/core/src/node/helper/config.ts +++ b/core/src/node/helper/config.ts @@ -1,5 +1,5 @@ import { AppConfiguration, SettingComponentProps } from '../../types' -import { join } from 'path' +import { join, resolve } from 'path' import fs from 'fs' import os from 'os' import childProcess from 'child_process' @@ -10,7 +10,10 @@ const configurationFileName = 'settings.json' // TODO: do not default the os.homedir const defaultJanDataFolder = join(os?.homedir() || '', 'jan') const defaultAppConfig: AppConfiguration = { - data_folder: defaultJanDataFolder, + data_folder: + process.env.CI === 'e2e' + ? process.env.APP_CONFIG_PATH ?? resolve('./test-data') + : defaultJanDataFolder, quick_ask: false, } @@ -20,6 +23,7 @@ const defaultAppConfig: AppConfiguration = { * @returns {AppConfiguration} The app configurations. */ export const getAppConfigurations = (): AppConfiguration => { + if (process.env.CI === 'e2e') return defaultAppConfig // Retrieve Application Support folder path // Fallback to user home directory if not found const configurationFile = getConfigurationFilePath() diff --git a/core/src/node/helper/path.ts b/core/src/node/helper/path.ts index a2d57ed3e..8115383bb 100644 --- a/core/src/node/helper/path.ts +++ b/core/src/node/helper/path.ts @@ -11,34 +11,41 @@ export function normalizeFilePath(path: string): string { return path.replace(/^(file:[\\/]+)([^:\s]+)$/, '$2') } -export async function appResourcePath(): Promise { - let electron: any = undefined - +/** + * App resources path + * Returns string - The current application directory. + */ +export function appResourcePath() { try { - const moduleName = 'electron' - electron = await import(moduleName) + const electron = require('electron') + // electron + if (electron && electron.protocol) { + let appPath = join(electron.app.getAppPath(), '..', 'app.asar.unpacked') + + if (!electron.app.isPackaged) { + // for development mode + appPath = join(electron.app.getAppPath()) + } + return appPath + } } catch (err) { console.error('Electron is not available') } - // electron - if (electron && electron.protocol) { - let appPath = join(electron.app.getAppPath(), '..', 'app.asar.unpacked') - - if (!electron.app.isPackaged) { - // for development mode - appPath = join(electron.app.getAppPath()) - } - return appPath - } // server return join(global.core.appPath(), '../../..') } export function validatePath(path: string) { - const janDataFolderPath = getJanDataFolderPath() + const appDataFolderPath = getJanDataFolderPath() + const resourcePath = appResourcePath() + const applicationSupportPath = global.core?.appPath() ?? resourcePath const absolutePath = resolve(__dirname, path) - if (!absolutePath.startsWith(janDataFolderPath)) { + if ( + ![appDataFolderPath, resourcePath, applicationSupportPath].some((whiteListedPath) => + absolutePath.startsWith(whiteListedPath) + ) + ) { throw new Error(`Invalid path: ${absolutePath}`) } } diff --git a/electron/utils/migration.ts b/electron/utils/migration.ts index defe0cebb..8c8d61a28 100644 --- a/electron/utils/migration.ts +++ b/electron/utils/migration.ts @@ -11,11 +11,7 @@ import { lstatSync, } from 'fs' import Store from 'electron-store' -import { - getJanExtensionsPath, - getJanDataFolderPath, - appResourcePath, -} from '@janhq/core/node' +import { getJanDataFolderPath, appResourcePath } from '@janhq/core/node' /** * Migrates the extensions & themes. @@ -43,9 +39,9 @@ async function migrateThemes() { if (!existsSync(join(getJanDataFolderPath(), 'themes'))) mkdirSync(join(getJanDataFolderPath(), 'themes'), { recursive: true }) - const themes = readdirSync(join(await appResourcePath(), 'themes')) + const themes = readdirSync(join(appResourcePath(), 'themes')) for (const theme of themes) { - const themePath = join(await appResourcePath(), 'themes', theme) + const themePath = join(appResourcePath(), 'themes', theme) if (existsSync(themePath) && !lstatSync(themePath).isDirectory()) { continue } diff --git a/web/app/layout.tsx b/web/app/layout.tsx index 01b2cabb4..5f14d6f5c 100644 --- a/web/app/layout.tsx +++ b/web/app/layout.tsx @@ -2,7 +2,6 @@ import { PropsWithChildren } from 'react' import { Metadata } from 'next' -import 'katex/dist/katex.min.css' import '@/styles/main.scss' export const metadata: Metadata = { diff --git a/web/styles/main.scss b/web/styles/main.scss index 89a64b8cb..3259f6c34 100644 --- a/web/styles/main.scss +++ b/web/styles/main.scss @@ -5,6 +5,7 @@ @import 'tailwindcss/utilities'; @import '@janhq/joi/dist/main.css'; +@import 'katex/dist/katex.min.css'; @import './base/global.scss';