Skip to content

Commit

Permalink
update common path (#34)
Browse files Browse the repository at this point in the history
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
ZHallen122 authored Nov 2, 2024
1 parent 82783f2 commit 7a120f1
Show file tree
Hide file tree
Showing 2 changed files with 180 additions and 157 deletions.
246 changes: 89 additions & 157 deletions backend/src/config/common-path.ts
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),
});
91 changes: 91 additions & 0 deletions frontend/src/config/common-path.ts
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);
}
};

0 comments on commit 7a120f1

Please sign in to comment.