watchtower-node-sdk
Version:
A TypeScript Node.js SDK for the Watchtower API, providing API key management, connection string generation, and more
135 lines (122 loc) • 4.72 kB
text/typescript
import { BaseEndpoint } from '../base';
import {
GetLatestRequest,
AnalyzeLogsRequest,
AnalyzeCurrentRequest,
AnalyzeCurrentResponse,
AnalysisResult
} from './types';
import { InvalidRequestError, AuthenticationError, ServerError } from '../../errors';
export class AnalyzeEndpoint extends BaseEndpoint {
constructor(client: any) {
super(client, '/api/analyze');
}
private validateRequiredKeys(data: { organization_apikey?: string; app_apikey?: string }) {
if (!data.organization_apikey) {
throw new InvalidRequestError('organization_apikey is required');
}
if (!data.app_apikey) {
throw new InvalidRequestError('app_apikey is required');
}
}
/**
* Get the latest analysis for an item
* @param data - The request parameters
* @returns Promise with the analysis result
* @throws {InvalidRequestError} If required fields are missing or invalid
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async getLatest(data: GetLatestRequest): Promise<AnalysisResult> {
this.validateRequiredKeys(data);
if (!data.item_id) {
throw new InvalidRequestError('item_id is required');
}
try {
return await this.get<AnalysisResult>('/latest', { params: data });
} catch (error: any) {
if (error.response?.status === 400) {
throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
}
if (error.response?.status === 401) {
throw new AuthenticationError('Invalid API keys');
}
if (error.response?.status === 500) {
throw new ServerError('Internal server error');
}
throw error;
}
}
/**
* Analyze logs for an item within a specified time range
* @param data - The request parameters
* @returns Promise with the analysis result
* @throws {InvalidRequestError} If required fields are missing or invalid
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async analyzeLogs(data: AnalyzeLogsRequest): Promise<AnalysisResult> {
this.validateRequiredKeys(data);
if (!data.item_id) {
throw new InvalidRequestError('item_id is required');
}
// Validate timestamp format if provided
if (data.after && !this.isValidISODate(data.after)) {
throw new InvalidRequestError('after must be a valid ISO 8601 timestamp');
}
if (data.before && !this.isValidISODate(data.before)) {
throw new InvalidRequestError('before must be a valid ISO 8601 timestamp');
}
try {
return await this.get<AnalysisResult>('', { params: data });
} catch (error: any) {
if (error.response?.status === 400) {
throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
}
if (error.response?.status === 401) {
throw new AuthenticationError('Invalid API keys');
}
if (error.response?.status === 500) {
throw new ServerError('Internal server error');
}
throw error;
}
}
/**
* Get the current analysis for an item
* @param data - The request parameters
* @returns Promise with the current analysis response
* @throws {InvalidRequestError} If required fields are missing or invalid
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async analyzeCurrent(data: AnalyzeCurrentRequest): Promise<AnalyzeCurrentResponse> {
this.validateRequiredKeys(data);
if (!data.item_id) {
throw new InvalidRequestError('item_id is required');
}
try {
return await this.get<AnalyzeCurrentResponse>('/current', { params: data });
} catch (error: any) {
if (error.response?.status === 400) {
throw new InvalidRequestError(error.response.data?.message || 'Invalid request');
}
if (error.response?.status === 401) {
throw new AuthenticationError('Invalid API keys');
}
if (error.response?.status === 500) {
throw new ServerError('Internal server error');
}
throw error;
}
}
/**
* Validate if a string is a valid ISO 8601 date
* @param dateString - The date string to validate
* @returns boolean indicating if the string is a valid ISO 8601 date
*/
private isValidISODate(dateString: string): boolean {
const date = new Date(dateString);
return date instanceof Date && !isNaN(date.getTime()) && dateString === date.toISOString();
}
}