doclyft
Version:
CLI for DocLyft - Interactive documentation generator with hosted documentation support
205 lines (204 loc) • 7.79 kB
JavaScript
;
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || (function () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.ActivityLogger = void 0;
const fs_1 = require("fs");
const path_1 = __importDefault(require("path"));
// Import the function directly inline to avoid module resolution issues
async function ensureSafeWorkingDirectory() {
const homeDir = process.env.HOME || process.env.USERPROFILE || process.cwd();
const doclyftDir = path_1.default.join(homeDir, '.doclyft');
try {
await fs_1.promises.mkdir(doclyftDir, { recursive: true });
return doclyftDir;
}
catch (error) {
console.warn('Warning: Could not create safe working directory, using current directory');
return process.cwd();
}
}
/**
* Activity logger for tracking CLI operations
*/
class ActivityLogger {
constructor() {
// Use async initialization pattern
this.logFilePath = ''; // Will be set during init
}
/**
* Initialize the logger
*/
async init() {
const safeDir = await ensureSafeWorkingDirectory();
this.logFilePath = path_1.default.join(safeDir, 'logs.json');
// Create log file if it doesn't exist
try {
await fs_1.promises.access(this.logFilePath);
}
catch {
await fs_1.promises.writeFile(this.logFilePath, JSON.stringify({ events: [] }, null, 2));
}
}
/**
* Add a log entry
*/
async logActivity(entry) {
// Ensure logger is initialized
if (!this.logFilePath) {
await this.init();
}
try {
// Read existing logs
const logsContent = await fs_1.promises.readFile(this.logFilePath, 'utf-8');
const logs = JSON.parse(logsContent);
// Add new entry
logs.events.push({
...entry,
timestamp: entry.timestamp || new Date().toISOString()
});
// Limit log size to prevent file growth issues (keep last 1000 entries)
if (logs.events.length > 1000) {
logs.events = logs.events.slice(-1000);
}
// Write updated logs
await fs_1.promises.writeFile(this.logFilePath, JSON.stringify(logs, null, 2));
}
catch (error) {
// Log failures shouldn't crash the application
console.warn(`Warning: Failed to log activity: ${error instanceof Error ? error.message : 'Unknown error'}`);
}
}
/**
* Get all logged activities
*/
async getActivities(limit = 50) {
// Ensure logger is initialized
if (!this.logFilePath) {
await this.init();
}
try {
const logsContent = await fs_1.promises.readFile(this.logFilePath, 'utf-8');
const logs = JSON.parse(logsContent);
// Return the most recent entries
return logs.events.slice(-limit);
}
catch (error) {
// Return empty array if can't read logs
return [];
}
}
/**
* Get activities filtered by type
*/
async getActivitiesByType(type, limit = 50) {
const activities = await this.getActivities(1000); // Get a larger batch for filtering
return activities
.filter(activity => activity.type === type)
.slice(-limit);
}
/**
* Get activities for a specific repository
*/
async getActivitiesByRepo(repo, limit = 50) {
const activities = await this.getActivities(1000);
return activities
.filter(activity => activity.repo === repo)
.slice(-limit);
}
/**
* Sync logs to the backend (enhanced with proper API integration)
*/
async syncLogsToBackend(apiClient) {
try {
const activities = await this.getActivities(100); // Sync last 100 activities
if (activities.length === 0) {
return true; // Nothing to sync
}
// Use injected API client or import default
if (!apiClient && typeof window === 'undefined') {
// In Node.js environment, dynamically import the API client
try {
const { default: defaultApiClient } = await Promise.resolve().then(() => __importStar(require('../services/api.js')));
apiClient = defaultApiClient;
}
catch (error) {
console.warn('Warning: Could not load API client for backend sync');
return false;
}
}
if (apiClient?.syncActivities) {
const response = await apiClient.syncActivities(activities);
if (response.ok) {
const result = await response.json();
console.log(`✅ Synced ${activities.length} activities to backend`);
return true;
}
}
else if (apiClient?.post) {
const response = await apiClient.post('/sync-cli-activity', {
activities,
cli_session_id: `cli_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`
});
if (response.ok) {
const result = await response.json();
console.log(`✅ Synced ${activities.length} activities to backend`);
return true;
}
}
return false;
}
catch (error) {
console.warn(`Warning: Failed to sync activities to backend: ${error instanceof Error ? error.message : 'Unknown error'}`);
return false;
}
}
/**
* Auto-sync activities to backend after logging (non-blocking)
*/
async logAndSync(entry, apiClient) {
// Log activity locally first
await this.logActivity(entry);
// Attempt backend sync without blocking
this.syncLogsToBackend(apiClient).catch(error => {
console.warn('Background sync failed:', error instanceof Error ? error.message : 'Unknown error');
});
}
}
exports.ActivityLogger = ActivityLogger;
// Export a singleton instance
exports.default = new ActivityLogger();