Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: allow user to move jan folder #1649

Merged
merged 3 commits into from
Jan 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions core/.prettierrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"semi": false,
"singleQuote": true,
"quoteProps": "consistent",
"trailingComma": "es5",
"endOfLine": "auto"
}
8 changes: 6 additions & 2 deletions core/src/api/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,16 @@ export enum AppRoute {
openExternalUrl = 'openExternalUrl',
openAppDirectory = 'openAppDirectory',
openFileExplore = 'openFileExplorer',
selectDirectory = 'selectDirectory',
getAppConfigurations = 'getAppConfigurations',
updateAppConfiguration = 'updateAppConfiguration',
relaunch = 'relaunch',
joinPath = 'joinPath',
baseName = 'baseName',
startServer = 'startServer',
stopServer = 'stopServer',
log = 'log'
log = 'log',
logServer = 'logServer',
}

export enum AppEvent {
Expand Down Expand Up @@ -55,7 +59,7 @@ export enum FileSystemRoute {
}
export enum FileManagerRoute {
syncFile = 'syncFile',
getUserSpace = 'getUserSpace',
getJanDataFolderPath = 'getJanDataFolderPath',
getResourcePath = 'getResourcePath',
fileStat = 'fileStat',
}
Expand Down
11 changes: 6 additions & 5 deletions core/src/core.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,10 +35,11 @@ const abortDownload: (fileName: string) => Promise<any> = (fileName) =>
global.core.api?.abortDownload(fileName)

/**
* Gets the user space path.
* @returns {Promise<any>} A Promise that resolves with the user space path.
* Gets Jan's data folder path.
*
* @returns {Promise<string>} A Promise that resolves with Jan's data folder path.
*/
const getUserSpace = (): Promise<string> => global.core.api?.getUserSpace()
const getJanDataFolderPath = (): Promise<string> => global.core.api?.getJanDataFolderPath()

/**
* Opens the file explorer at a specific path.
Expand Down Expand Up @@ -103,12 +104,12 @@ export {
executeOnMain,
downloadFile,
abortDownload,
getUserSpace,
getJanDataFolderPath,
openFileExplorer,
getResourcePath,
joinPath,
openExternalUrl,
baseName,
log,
FileStat
FileStat,
}
34 changes: 17 additions & 17 deletions core/src/node/api/common/builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,10 @@ import fs from 'fs'
import { JanApiRouteConfiguration, RouteConfiguration } from './configuration'
import { join } from 'path'
import { ContentType, MessageStatus, Model, ThreadMessage } from './../../../index'

const os = require('os')

const path = join(os.homedir(), 'jan')
import { getJanDataFolderPath } from '../../utils'

export const getBuilder = async (configuration: RouteConfiguration) => {
const directoryPath = join(path, configuration.dirName)
const directoryPath = join(getJanDataFolderPath(), configuration.dirName)
try {
if (!fs.existsSync(directoryPath)) {
console.debug('model folder not found')
Expand Down Expand Up @@ -72,7 +69,7 @@ export const deleteBuilder = async (configuration: RouteConfiguration, id: strin
}
}

const directoryPath = join(path, configuration.dirName)
const directoryPath = join(getJanDataFolderPath(), configuration.dirName)
try {
const data = await retrieveBuilder(configuration, id)
if (!data) {
Expand All @@ -94,7 +91,7 @@ export const deleteBuilder = async (configuration: RouteConfiguration, id: strin
}

export const getMessages = async (threadId: string): Promise<ThreadMessage[]> => {
const threadDirPath = join(path, 'threads', threadId)
const threadDirPath = join(getJanDataFolderPath(), 'threads', threadId)
const messageFile = 'messages.jsonl'
try {
const files: string[] = fs.readdirSync(threadDirPath)
Expand Down Expand Up @@ -155,7 +152,7 @@ export const createThread = async (thread: any) => {
created: Date.now(),
updated: Date.now(),
}
const threadDirPath = join(path, 'threads', updatedThread.id)
const threadDirPath = join(getJanDataFolderPath(), 'threads', updatedThread.id)
const threadJsonPath = join(threadDirPath, threadMetadataFileName)

if (!fs.existsSync(threadDirPath)) {
Expand Down Expand Up @@ -189,7 +186,7 @@ export const updateThread = async (threadId: string, thread: any) => {
updated: Date.now(),
}
try {
const threadDirPath = join(path, 'threads', updatedThread.id)
const threadDirPath = join(getJanDataFolderPath(), 'threads', updatedThread.id)
const threadJsonPath = join(threadDirPath, threadMetadataFileName)

await fs.writeFileSync(threadJsonPath, JSON.stringify(updatedThread, null, 2))
Expand Down Expand Up @@ -231,7 +228,7 @@ export const createMessage = async (threadId: string, message: any) => {
],
}

const threadDirPath = join(path, 'threads', threadId)
const threadDirPath = join(getJanDataFolderPath(), 'threads', threadId)
const threadMessagePath = join(threadDirPath, threadMessagesFileName)

if (!fs.existsSync(threadDirPath)) {
Expand All @@ -246,17 +243,20 @@ export const createMessage = async (threadId: string, message: any) => {
}
}

export const downloadModel = async (modelId: string, network?: { proxy?: string, ignoreSSL?: boolean }) => {
const strictSSL = !network?.ignoreSSL;
const proxy = network?.proxy?.startsWith('http') ? network.proxy : undefined;
export const downloadModel = async (
modelId: string,
network?: { proxy?: string; ignoreSSL?: boolean }
) => {
const strictSSL = !network?.ignoreSSL
const proxy = network?.proxy?.startsWith('http') ? network.proxy : undefined
const model = await retrieveBuilder(JanApiRouteConfiguration.models, modelId)
if (!model || model.object !== 'model') {
return {
message: 'Model not found',
}
}

const directoryPath = join(path, 'models', modelId)
const directoryPath = join(getJanDataFolderPath(), 'models', modelId)
if (!fs.existsSync(directoryPath)) {
fs.mkdirSync(directoryPath)
}
Expand All @@ -265,7 +265,7 @@ export const downloadModel = async (modelId: string, network?: { proxy?: string,
const modelBinaryPath = join(directoryPath, modelId)

const request = require('request')
const rq = request({url: model.source_url, strictSSL, proxy })
const rq = request({ url: model.source_url, strictSSL, proxy })
const progress = require('request-progress')
progress(rq, {})
.on('progress', function (state: any) {
Expand Down Expand Up @@ -316,7 +316,7 @@ export const chatCompletions = async (request: any, reply: any) => {
reply.raw.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
Connection: 'keep-alive',
'Connection': 'keep-alive',
})

const headers: Record<string, any> = {
Expand Down Expand Up @@ -347,7 +347,7 @@ const getEngineConfiguration = async (engineId: string) => {
if (engineId !== 'openai') {
return undefined
}
const directoryPath = join(path, 'engines')
const directoryPath = join(getJanDataFolderPath(), 'engines')
const filePath = join(directoryPath, `${engineId}.json`)
const data = await fs.readFileSync(filePath, 'utf-8')
return JSON.parse(data)
Expand Down
16 changes: 8 additions & 8 deletions core/src/node/api/routes/download.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import { DownloadRoute } from "../../../api";
import { join } from "path";
import { userSpacePath } from "../../extension/manager";
import { DownloadManager } from "../../download";
import { HttpServer } from "../HttpServer";
import { createWriteStream } from "fs";
import { DownloadRoute } from '../../../api'
import { join } from 'path'
import { DownloadManager } from '../../download'
import { HttpServer } from '../HttpServer'
import { createWriteStream } from 'fs'
import { getJanDataFolderPath } from '../../utils'
import { normalizeFilePath } from "../../path";

export const downloadRouter = async (app: HttpServer) => {
Expand All @@ -13,7 +13,7 @@ export const downloadRouter = async (app: HttpServer) => {
const body = JSON.parse(req.body as any);
const normalizedArgs = body.map((arg: any) => {
if (typeof arg === "string") {
return join(userSpacePath, normalizeFilePath(arg));
return join(getJanDataFolderPath(), normalizeFilePath(arg));
}
return arg;
});
Expand Down Expand Up @@ -44,7 +44,7 @@ export const downloadRouter = async (app: HttpServer) => {
const body = JSON.parse(req.body as any);
const normalizedArgs = body.map((arg: any) => {
if (typeof arg === "string") {
return join(userSpacePath, normalizeFilePath(arg));
return join(getJanDataFolderPath(), normalizeFilePath(arg));
}
return arg;
});
Expand Down
10 changes: 5 additions & 5 deletions core/src/node/api/routes/extension.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,20 @@
import { join, extname } from 'path'
import { ExtensionRoute } from '../../../api/index'
import { userSpacePath } from '../../extension/manager'
import { ModuleManager } from '../../module'
import { getActiveExtensions, installExtensions } from '../../extension/store'
import { HttpServer } from '../HttpServer'

import { readdirSync } from 'fs'
import { getJanExtensionsPath } from '../../utils'

export const extensionRouter = async (app: HttpServer) => {
// TODO: Share code between node projects
app.post(`/${ExtensionRoute.getActiveExtensions}`, async (req, res) => {
app.post(`/${ExtensionRoute.getActiveExtensions}`, async (_req, res) => {
const activeExtensions = await getActiveExtensions()
res.status(200).send(activeExtensions)
})

app.post(`/${ExtensionRoute.baseExtensions}`, async (req, res) => {
app.post(`/${ExtensionRoute.baseExtensions}`, async (_req, res) => {
const baseExtensionPath = join(__dirname, '..', '..', '..', 'pre-install')
const extensions = readdirSync(baseExtensionPath)
.filter((file) => extname(file) === '.tgz')
Expand All @@ -23,7 +23,7 @@ export const extensionRouter = async (app: HttpServer) => {
res.status(200).send(extensions)
})

app.post(`/${ExtensionRoute.installExtension}`, async (req, res) => {
app.post(`/${ExtensionRoute.installExtension}`, async (req) => {
const extensions = req.body as any
const installed = await installExtensions(JSON.parse(extensions)[0])
return JSON.parse(JSON.stringify(installed))
Expand All @@ -32,7 +32,7 @@ export const extensionRouter = async (app: HttpServer) => {
app.post(`/${ExtensionRoute.invokeExtensionFunc}`, async (req, res) => {
const args = JSON.parse(req.body as any)
console.debug(args)
const module = await import(join(userSpacePath, 'extensions', args[0]))
const module = await import(join(getJanExtensionsPath(), args[0]))

ModuleManager.instance.setModule(args[0], module)
const method = args[1]
Expand Down
2 changes: 1 addition & 1 deletion core/src/node/api/routes/fileManager.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ import { HttpServer } from '../../index'
export const fsRouter = async (app: HttpServer) => {
app.post(`/app/${FileManagerRoute.syncFile}`, async (request: any, reply: any) => {})

app.post(`/app/${FileManagerRoute.getUserSpace}`, async (request: any, reply: any) => {})
app.post(`/app/${FileManagerRoute.getJanDataFolderPath}`, async (request: any, reply: any) => {})

app.post(`/app/${FileManagerRoute.getResourcePath}`, async (request: any, reply: any) => {})

Expand Down
4 changes: 2 additions & 2 deletions core/src/node/api/routes/fs.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { FileSystemRoute } from '../../../api'
import { join } from 'path'
import { HttpServer } from '../HttpServer'
import { userSpacePath } from '../../extension/manager'
import { getJanDataFolderPath } from '../../utils'

export const fsRouter = async (app: HttpServer) => {
const moduleName = 'fs'
Expand All @@ -14,7 +14,7 @@ export const fsRouter = async (app: HttpServer) => {
return mdl[route](
...body.map((arg: any) =>
typeof arg === 'string' && arg.includes('file:/')
? join(userSpacePath, arg.replace('file:/', ''))
? join(getJanDataFolderPath(), arg.replace('file:/', ''))
: arg,
),
)
Expand Down
13 changes: 7 additions & 6 deletions core/src/node/extension/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default class Extension {
const pacote = await import('pacote')
await pacote.extract(
this.specifier,
join(ExtensionManager.instance.extensionsPath ?? '', this.name ?? ''),
join(ExtensionManager.instance.getExtensionsPath() ?? '', this.name ?? ''),
this.installOptions,
)

Expand Down Expand Up @@ -166,9 +166,9 @@ export default class Extension {
* @returns the latest available version if a new version is available or false if not.
*/
async isUpdateAvailable() {
return import('pacote').then((pacote) => {
if (this.origin) {
return pacote.manifest(this.origin).then((mnf) => {
return import('pacote').then((pacote) => {
if (this.origin) {
return pacote.manifest(this.origin).then((mnf) => {
return mnf.version !== this.version ? mnf.version : false
})
}
Expand All @@ -179,8 +179,9 @@ export default class Extension {
* Remove extension and refresh renderers.
* @returns {Promise}
*/
async uninstall() {
const extPath = resolve(ExtensionManager.instance.extensionsPath ?? '', this.name ?? '')
async uninstall(): Promise<void> {
const path = ExtensionManager.instance.getExtensionsPath()
const extPath = resolve(path ?? '', this.name ?? '')
await rmdirSync(extPath, { recursive: true })

this.emitUpdate()
Expand Down
10 changes: 5 additions & 5 deletions core/src/node/extension/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,17 +35,17 @@ async function registerExtensionProtocol() {
let electron: any = undefined

try {
const moduleName = "electron"
const moduleName = 'electron'
electron = await import(moduleName)
} catch (err) {
console.error('Electron is not available')
}

const extensionPath = ExtensionManager.instance.getExtensionsPath()
if (electron) {
return electron.protocol.registerFileProtocol('extension', (request: any, callback: any) => {
const entry = request.url.substr('extension://'.length - 1)

const url = normalize(ExtensionManager.instance.extensionsPath + entry)
const url = normalize(extensionPath + entry)
callback({ path: url })
})
}
Expand Down Expand Up @@ -120,7 +120,7 @@ function loadExtension(ext: any) {
* @returns {extensionManager} A set of functions used to manage the extension lifecycle.
*/
export function getStore() {
if (!ExtensionManager.instance.extensionsPath) {
if (!ExtensionManager.instance.getExtensionsFile()) {
throw new Error(
'The extension path has not yet been set up. Please run useExtensions before accessing the store',
)
Expand All @@ -133,4 +133,4 @@ export function getStore() {
getActiveExtensions,
removeExtension,
}
}
}
Loading
Loading