@statezero/statezero-tunnel
Version:
Tunnelmole client for StateZero users to create secure tunnels to their local services.
77 lines • 2.61 kB
JavaScript
import fs from 'fs';
import path from 'path';
import os from 'os';
import crypto from 'crypto';
export class ProjectManager {
constructor() {
this.configPath = path.join(os.homedir(), '.tunnelmole-projects.json');
this.store = this.loadStore();
}
loadStore() {
try {
if (fs.existsSync(this.configPath)) {
const data = fs.readFileSync(this.configPath, 'utf8');
return JSON.parse(data);
}
}
catch (error) {
console.warn('Failed to load project store:', error);
}
return { projects: [] };
}
saveStore() {
try {
fs.writeFileSync(this.configPath, JSON.stringify(this.store, null, 2));
}
catch (error) {
console.error('Failed to save project store:', error);
}
}
getProjects() {
return this.store.projects.sort((a, b) => new Date(b.lastUsed).getTime() - new Date(a.lastUsed).getTime());
}
generateUniqueId() {
return crypto.randomBytes(8).toString('hex');
}
createProject(name, userEmail, userName) {
const project = {
id: this.generateUniqueId(),
name,
subdomain: this.generateSubdomain(name),
userEmail,
userName,
createdAt: new Date().toISOString(),
lastUsed: new Date().toISOString()
};
this.store.projects.push(project);
this.saveStore();
return project;
}
generateSubdomain(projectName) {
// Create a consistent subdomain based on project name + unique suffix
const sanitized = projectName.toLowerCase().replace(/[^a-z0-9]/g, '');
const truncated = sanitized.substring(0, 10); // Limit length
const suffix = crypto.createHash('md5').update(projectName).digest('hex').substring(0, 6);
return `${truncated}-${suffix}`;
}
updateLastUsed(projectId) {
const project = this.store.projects.find(p => p.id === projectId);
if (project) {
project.lastUsed = new Date().toISOString();
this.saveStore();
}
}
deleteProject(projectId) {
const index = this.store.projects.findIndex(p => p.id === projectId);
if (index !== -1) {
this.store.projects.splice(index, 1);
this.saveStore();
return true;
}
return false;
}
findByName(name) {
return this.store.projects.find(p => p.name.toLowerCase() === name.toLowerCase());
}
}
//# sourceMappingURL=project-manager.js.map