-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
backend export functions rather then class easy root .codefox models config json INDEX sqlite database Some of them do not need to be placed in the root, but in the project relative. Docker will package them when the time comes. projects readme frontend .codefox-client .cache [user-id] hashed decode [projectid] content <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit - **New Features** - Introduced new functions for managing project directories and content, enhancing file operations. - Added utility functions for directory management, ensuring necessary directories exist. - Implemented a new method for hashing user IDs for cache management. - Added asynchronous functions for reading, writing, and deleting project content files. - Enhanced management of cache directories in the client application. - **Refactor** - Transitioned from a class-based structure to a module-based approach for improved clarity and modularity. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
- Loading branch information
1 parent
82783f2
commit 7a120f1
Showing
2 changed files
with
180 additions
and
157 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,161 +1,93 @@ | ||
import path from 'path'; | ||
import os from 'os'; | ||
import { name } from '../../package.json'; | ||
import { existsSync, mkdirSync, promises } from 'fs-extra'; | ||
|
||
export class CodeFoxPaths { | ||
private static readonly APP_NAME = name; | ||
private static readonly ROOT_DIR = path.join( | ||
os.homedir(), | ||
`.${CodeFoxPaths.APP_NAME}`, | ||
import { createHash } from 'crypto'; | ||
|
||
// Constants for base directories | ||
const APP_NAME = 'codefox'; | ||
const ROOT_DIR = path.join(os.homedir(), `.${APP_NAME}`); | ||
|
||
// Utility function to ensure a directory exists | ||
const ensureDir = (dirPath: string): string => { | ||
if (!existsSync(dirPath)) { | ||
mkdirSync(dirPath, { recursive: true }); | ||
} | ||
return dirPath; | ||
}; | ||
|
||
// ----------- We need path traverse Protection after we decide how we read and store the file !!!!!!!!!!!!! ------------ | ||
// ------------------------------------------------------------------------------------------------------------- | ||
|
||
// Root Directory Accessor | ||
export const getRootDir = (): string => ensureDir(ROOT_DIR); | ||
|
||
// Configuration Paths | ||
export const getConfigDir = (): string => | ||
ensureDir(path.join(getRootDir(), 'config')); | ||
export const getConfigPath = (configName: string): string => | ||
path.join(getConfigDir(), `${configName}.json`); | ||
|
||
// Models Directory | ||
export const getModelsDir = (): string => | ||
ensureDir(path.join(getRootDir(), 'models')); | ||
export const getModelPath = (modelName: string): string => | ||
path.join(getModelsDir(), modelName); | ||
|
||
// Project-Specific Paths | ||
export const getProjectsDir = (): string => | ||
ensureDir(path.join(getRootDir(), 'projects')); | ||
export const getProjectPath = (projectId: string): string => | ||
ensureDir(path.join(getProjectsDir(), projectId)); | ||
export const getProjectSourceDir = (projectId: string): string => | ||
ensureDir(path.join(getProjectPath(projectId), 'src')); | ||
export const getProjectGeneratedDir = (projectId: string): string => | ||
ensureDir(path.join(getProjectPath(projectId), 'generated')); | ||
export const getProjectTestsDir = (projectId: string): string => | ||
ensureDir(path.join(getProjectPath(projectId), 'tests')); | ||
|
||
// Database Paths | ||
export const getDatabaseDir = (): string => | ||
ensureDir(path.join(getRootDir(), 'data')); | ||
export const getDatabasePath = (): string => | ||
path.join(getDatabaseDir(), 'codefox.db'); | ||
|
||
// Vector Database (INDEX) Path | ||
export const getIndexDir = (): string => | ||
ensureDir(path.join(getRootDir(), 'INDEX')); | ||
export const getIndexFilePath = (indexFileName: string): string => | ||
path.join(getIndexDir(), indexFileName); | ||
|
||
// Temporary files | ||
export const getTempDir = (): string => { | ||
const tempDir = path.join(ROOT_DIR, 'temp'); | ||
if (!existsSync(tempDir)) { | ||
mkdirSync(tempDir, { recursive: true }); | ||
} | ||
return tempDir; | ||
}; | ||
|
||
// Utility Functions | ||
export const exists = (filePath: string): boolean => existsSync(filePath); | ||
|
||
export const cleanTempDir = async (): Promise<void> => { | ||
const tempDir = getTempDir(); | ||
const files = await promises.readdir(tempDir); | ||
await Promise.all( | ||
files.map((file) => promises.unlink(path.join(tempDir, file))), | ||
); | ||
|
||
/** | ||
* Internal helper to ensure a directory exists before returning its path | ||
* @param dirPath The directory path to check/create | ||
* @returns The same directory path | ||
*/ | ||
private static ensureDir(dirPath: string): string { | ||
if (!existsSync(path.dirname(dirPath))) { | ||
this.ensureDir(path.dirname(dirPath)); | ||
} | ||
if (!existsSync(dirPath)) { | ||
mkdirSync(dirPath, { recursive: true }); | ||
} | ||
return dirPath; | ||
} | ||
|
||
/** | ||
* Root Directory | ||
*/ | ||
public static getRootDir(): string { | ||
return this.ensureDir(CodeFoxPaths.ROOT_DIR); | ||
} | ||
|
||
/** | ||
* Models Directory | ||
*/ | ||
public static getModelsDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'models')); | ||
} | ||
|
||
public static getModelPath(modelName: string): string { | ||
return path.join(this.getModelsDir(), modelName); | ||
} | ||
|
||
/** | ||
* Projects Directory | ||
*/ | ||
public static getProjectsDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'projects')); | ||
} | ||
|
||
public static getProjectPath(projectId: string): string { | ||
return this.ensureDir(path.join(this.getProjectsDir(), projectId)); | ||
} | ||
|
||
public static getProjectSourceDir(projectId: string): string { | ||
return this.ensureDir(path.join(this.getProjectPath(projectId), 'src')); | ||
} | ||
|
||
public static getProjectGeneratedDir(projectId: string): string { | ||
return this.ensureDir( | ||
path.join(this.getProjectPath(projectId), 'generated'), | ||
); | ||
} | ||
|
||
public static getProjectTestsDir(projectId: string): string { | ||
return this.ensureDir(path.join(this.getProjectPath(projectId), 'tests')); | ||
} | ||
|
||
/** | ||
* Database | ||
*/ | ||
public static getDatabaseDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'data')); | ||
} | ||
|
||
public static getDatabasePath(): string { | ||
this.getDatabaseDir(); // Ensure database directory exists | ||
return path.join(this.getDatabaseDir(), 'codefox.db'); | ||
} | ||
|
||
/** | ||
* Configuration | ||
*/ | ||
public static getConfigDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'config')); | ||
} | ||
|
||
public static getConfigPath(configName: string): string { | ||
this.getConfigDir(); // Ensure config directory exists | ||
return path.join(this.getConfigDir(), `${configName}.json`); | ||
} | ||
|
||
/** | ||
* Cache | ||
*/ | ||
public static getCacheDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'cache')); | ||
} | ||
|
||
/** | ||
* Logs | ||
*/ | ||
public static getLogsDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'logs')); | ||
} | ||
|
||
/** | ||
* Temporary files | ||
*/ | ||
public static getTempDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'temp')); | ||
} | ||
|
||
/** | ||
* Templates | ||
*/ | ||
public static getTemplatesDir(): string { | ||
return this.ensureDir(path.join(this.getRootDir(), 'templates')); | ||
} | ||
|
||
public static getPromptTemplatePath(templateName: string): string { | ||
this.getTemplatesDir(); // Ensure templates directory exists | ||
return path.join(this.getTemplatesDir(), `${templateName}.txt`); | ||
} | ||
|
||
/** | ||
* Utility Methods | ||
*/ | ||
public static resolvePath(...pathSegments: string[]): string { | ||
const resolvedPath = path.join(this.getRootDir(), ...pathSegments); | ||
return this.ensureDir(path.dirname(resolvedPath)); | ||
} | ||
|
||
public static exists(filePath: string): boolean { | ||
return existsSync(filePath); | ||
} | ||
|
||
public static async cleanTempDir(): Promise<void> { | ||
const tempDir = this.getTempDir(); | ||
const files = await promises.readdir(tempDir); | ||
await Promise.all( | ||
files.map((file) => promises.unlink(path.join(tempDir, file))), | ||
); | ||
} | ||
|
||
public static getProjectStructure(projectId: string): { | ||
root: string; | ||
src: string; | ||
generated: string; | ||
tests: string; | ||
} { | ||
return { | ||
root: this.getProjectPath(projectId), | ||
src: this.getProjectSourceDir(projectId), | ||
generated: this.getProjectGeneratedDir(projectId), | ||
tests: this.getProjectTestsDir(projectId), | ||
}; | ||
} | ||
} | ||
}; | ||
|
||
// Access Project Structure | ||
export const getProjectStructure = ( | ||
projectId: string, | ||
): { | ||
root: string; | ||
src: string; | ||
generated: string; | ||
tests: string; | ||
} => ({ | ||
root: getProjectPath(projectId), | ||
src: getProjectSourceDir(projectId), | ||
generated: getProjectGeneratedDir(projectId), | ||
tests: getProjectTestsDir(projectId), | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
import path from 'path'; | ||
import { existsSync, mkdirSync, promises as fsPromises } from 'fs-extra'; | ||
import { createHash } from 'crypto'; | ||
|
||
// Constants for the frontend root directory | ||
const FRONTEND_ROOT_DIR = path.resolve(__dirname, '../.codefox-client'); | ||
const CLIENT_CACHE_DIR = path.join(FRONTEND_ROOT_DIR, '.cache'); | ||
|
||
// Utility function to ensure a directory exists | ||
const ensureDir = (dirPath: string): string => { | ||
if (!existsSync(dirPath)) { | ||
mkdirSync(dirPath, { recursive: true }); | ||
} | ||
return dirPath; | ||
}; | ||
|
||
// ----------- We need path traverse Protection after we decide how we read and store the file !!!!!!!!!!!!! ------------ | ||
// ------------------------------------------------------------------------------------------------------------- | ||
|
||
// Step 1: Frontend Root Directory | ||
export const getFrontendRootDir = (): string => ensureDir(FRONTEND_ROOT_DIR); | ||
|
||
// Step 2: Cache Directory | ||
export const getCacheDir = (): string => ensureDir(CLIENT_CACHE_DIR); | ||
|
||
// Step 3: User Cache Directory | ||
export const getUserCacheDir = (userId: string): string => { | ||
const hashedUserId = hashUserId(userId); | ||
return ensureDir(path.join(getCacheDir(), hashedUserId)); | ||
}; | ||
|
||
// Step 4: Project Cache Directory within a User's Directory | ||
export const getProjectCacheDir = ( | ||
userId: string, | ||
projectId: string | ||
): string => { | ||
return ensureDir(path.join(getUserCacheDir(userId), projectId)); | ||
}; | ||
|
||
// Step 5: Content Directory within a Project's Cache Directory | ||
export const getProjectContentDir = ( | ||
userId: string, | ||
projectId: string | ||
): string => { | ||
return ensureDir(path.join(getProjectCacheDir(userId, projectId), 'content')); | ||
}; | ||
|
||
// Updated function to get the full path to a specific file within the 'content' directory | ||
export const getProjectContentPath = ( | ||
userId: string, | ||
projectId: string, | ||
fileName: string | ||
): string => { | ||
return path.join(getProjectContentDir(userId, projectId), fileName); | ||
}; | ||
|
||
// Helper function to hash user IDs for unique cache directories | ||
const hashUserId = (userId: string): string => { | ||
return createHash('md5').update(userId).digest('hex'); | ||
}; | ||
|
||
// Utility Functions for File Operations | ||
export const writeProjectContent = async ( | ||
userId: string, | ||
projectId: string, | ||
fileName: string, | ||
content: string | ||
): Promise<void> => { | ||
const contentPath = getProjectContentPath(userId, projectId, fileName); | ||
await fsPromises.writeFile(contentPath, content, 'utf8'); | ||
}; | ||
|
||
export const readProjectContent = async ( | ||
userId: string, | ||
projectId: string, | ||
fileName: string | ||
): Promise<string> => { | ||
const contentPath = getProjectContentPath(userId, projectId, fileName); | ||
return fsPromises.readFile(contentPath, 'utf8'); | ||
}; | ||
|
||
export const deleteProjectContent = async ( | ||
userId: string, | ||
projectId: string, | ||
fileName: string | ||
): Promise<void> => { | ||
const contentPath = getProjectContentPath(userId, projectId, fileName); | ||
if (existsSync(contentPath)) { | ||
await fsPromises.unlink(contentPath); | ||
} | ||
}; |