UNPKG

@smartsamurai/krapi-sdk

Version:

KRAPI TypeScript SDK - Easy-to-use client SDK for connecting to self-hosted KRAPI servers (like Appwrite SDK)

187 lines (174 loc) 6.54 kB
/** * Activity HTTP Client for KRAPI SDK * * HTTP-based activity logging for frontend applications. * Provides activity logging, querying, and statistics. * * @module http-clients/activity-http-client * @example * const client = new ActivityHttpClient({ baseUrl: 'https://api.example.com' }); * await client.log({ action: 'created', resource_type: 'document' }); */ import { ActivityLog, ActivityQuery } from "../activity-logger"; import { ApiResponse, PaginatedResponse } from "../core"; import { KrapiError } from "../core/krapi-error"; import { BaseHttpClient } from "./base-http-client"; /** * Activity HTTP Client * * HTTP client for activity logging operations. * * @class ActivityHttpClient * @extends {BaseHttpClient} */ export class ActivityHttpClient extends BaseHttpClient { /** * Log an activity event * * @param {Omit<ActivityLog, "id" | "timestamp">} activityData - Activity data * @returns {Promise<ApiResponse<ActivityLog>>} Created activity log */ async log( activityData: Omit<ActivityLog, "id" | "timestamp"> ): Promise<ApiResponse<ActivityLog>> { return this.post<ActivityLog>("/activity/log", activityData); } /** * Query activity logs * * @param {ActivityQuery} query - Query parameters * @returns {Promise<PaginatedResponse<ActivityLog>>} Activity logs with pagination */ async query( query: ActivityQuery ): Promise<ApiResponse<PaginatedResponse<ActivityLog>>> { const params = new URLSearchParams(); if (query.user_id) params.append("user_id", query.user_id); if (query.project_id) params.append("project_id", query.project_id); if (query.action) params.append("action", query.action); if (query.resource_type) params.append("resource_type", query.resource_type); if (query.resource_id) params.append("resource_id", query.resource_id); if (query.severity) params.append("severity", query.severity); if (query.start_date) { // Ensure start_date is a Date object before calling toISOString() const startDate = query.start_date instanceof Date ? query.start_date : new Date(query.start_date); // Validate date is not invalid if (isNaN(startDate.getTime())) { throw KrapiError.validationError("Invalid start_date provided to activity query", "start_date"); } params.append("start_date", startDate.toISOString()); } if (query.end_date) { // Ensure end_date is a Date object before calling toISOString() const endDate = query.end_date instanceof Date ? query.end_date : new Date(query.end_date); // Validate date is not invalid if (isNaN(endDate.getTime())) { throw KrapiError.validationError("Invalid end_date provided to activity query", "end_date"); } params.append("end_date", endDate.toISOString()); } if (query.limit) params.append("limit", query.limit.toString()); if (query.offset) params.append("offset", query.offset.toString()); // Build URL - handle case where no parameters are provided const queryString = params.toString(); const endpoint = queryString ? `/activity/query?${queryString}` : `/activity/query`; return this.get<PaginatedResponse<ActivityLog>>(endpoint); } /** * Get activity statistics * * @param {string} [projectId] - Optional project ID * @param {number} [days=30] - Number of days to analyze * @returns {Promise<ApiResponse<{ total_actions: number; actions_by_type: Record<string, number>; actions_by_severity: Record<string, number>; actions_by_user: Record<string, number> }>>} Activity statistics */ async getStats( projectId?: string, days = 30 ): Promise< ApiResponse<{ total_actions: number; actions_by_type: Record<string, number>; actions_by_severity: Record<string, number>; actions_by_user: Record<string, number>; }> > { const params = new URLSearchParams(); if (projectId) params.append("project_id", projectId); params.append("days", days.toString()); return this.get(`/activity/stats?${params.toString()}`); } /** * Get recent activity * * @param {string} [userId] - Optional user ID * @param {string} [projectId] - Optional project ID * @param {number} [limit=50] - Maximum number of results * @returns {Promise<ApiResponse<ActivityLog[]>>} Recent activity logs */ async getRecent( userId?: string, projectId?: string, limit = 50 ): Promise<ApiResponse<ActivityLog[]>> { const params = new URLSearchParams(); if (userId) params.append("user_id", userId); if (projectId) params.append("project_id", projectId); params.append("limit", limit.toString()); return this.get<ActivityLog[]>(`/activity/recent?${params.toString()}`); } /** * Get user timeline * * @param {string} userId - User ID * @param {Object} [options] - Query options * @param {number} [options.limit] - Maximum number of results * @param {number} [options.offset] - Number of results to skip * @param {Date} [options.start_date] - Start date filter * @param {Date} [options.end_date] - End date filter * @returns {Promise<PaginatedResponse<ActivityLog>>} User activity timeline */ async getUserTimeline( userId: string, options?: { limit?: number; offset?: number; start_date?: Date; end_date?: Date; } ): Promise<ApiResponse<PaginatedResponse<ActivityLog>>> { const params = new URLSearchParams(); params.append("user_id", userId); if (options?.limit) params.append("limit", options.limit.toString()); if (options?.offset) params.append("offset", options.offset.toString()); if (options?.start_date) params.append("start_date", options.start_date.toISOString()); if (options?.end_date) params.append("end_date", options.end_date.toISOString()); return this.get<PaginatedResponse<ActivityLog>>( `/activity/users/${userId}/timeline?${params.toString()}` ); } /** * Cleanup old activity logs * * @param {number} [daysToKeep=90] - Number of days to keep * @returns {Promise<ApiResponse<{ success: boolean; deleted_count: number }>>} Cleanup result */ async cleanup( daysToKeep = 90 ): Promise<ApiResponse<{ success: boolean; deleted_count: number }>> { return this.post<{ success: boolean; deleted_count: number }>( "/activity/cleanup", { days_to_keep: daysToKeep } ); } }