watchtower-node-sdk
Version:
A TypeScript Node.js SDK for the Watchtower API, providing API key management, connection string generation, and more
187 lines (171 loc) • 6.54 kB
text/typescript
import { BaseEndpoint } from '../base';
import {
CreateLogRequest,
BatchLogRequest,
BatchLogResponse,
GetLogsRequest,
PaginatedLogResponse,
GetLatestLogsRequest,
LatestLogsResponse,
GetLogByIdRequest,
LogResponse,
ParsedLogResponse
} from './types';
import { InvalidRequestError, AuthenticationError, NotFoundError, ServerError, BATCH_SIZE_LIMIT } from '../../errors';
export class LogsEndpoint extends BaseEndpoint {
constructor(client: any) {
super(client, '/api/logs');
}
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');
}
}
private validateTimestamp(timestamp: string) {
if (!/^\d{4}-\d{2}-\d{2}T\d{2}:\d{2}:\d{2}(\.\d{3})?Z$/.test(timestamp)) {
throw new InvalidRequestError('timestamp must be in ISO 8601 format');
}
}
/**
* Create a log entry
* @param data - The log creation request
* @returns Promise that resolves if the log is created (201)
* @throws {InvalidRequestError} If required fields are missing or invalid
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async createLog(data: CreateLogRequest): Promise<void> {
this.validateRequiredKeys(data);
this.validateTimestamp(data.timestamp);
try {
await this.post<void>('', 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;
}
}
/**
* Create a batch of log entries
* @param data - The batch log creation request
* @returns Promise with the batch log response
* @throws {InvalidRequestError} If batch size exceeds limit or required fields are missing
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async createBatchLogs(data: BatchLogRequest): Promise<BatchLogResponse> {
this.validateRequiredKeys(data);
if (data.logs.length > BATCH_SIZE_LIMIT) {
throw new InvalidRequestError(`Batch size cannot exceed ${BATCH_SIZE_LIMIT} logs`);
}
data.logs.forEach(log => {
this.validateTimestamp(log.timestamp);
});
try {
return await this.post<BatchLogResponse>('/batch', 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 logs for a specific item
* @param data - The get logs request parameters
* @returns Promise with the paginated log response
* @throws {InvalidRequestError} If required fields are missing
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async getLogs(data: GetLogsRequest): Promise<PaginatedLogResponse> {
this.validateRequiredKeys(data);
if (data.before) this.validateTimestamp(data.before);
if (data.after) this.validateTimestamp(data.after);
try {
return await this.get<PaginatedLogResponse>('', { 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 latest logs for a specific item
* @param data - The get latest logs request parameters
* @returns Promise with the latest logs response
* @throws {InvalidRequestError} If required fields are missing
* @throws {AuthenticationError} If API keys are invalid
* @throws {ServerError} If server encounters an error
*/
async getLatestLogs(data: GetLatestLogsRequest): Promise<LatestLogsResponse> {
this.validateRequiredKeys(data);
try {
return await this.get<LatestLogsResponse>('/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;
}
}
/**
* Get a specific log by ID
* @param id - The log ID
* @param data - The get log by ID request parameters
* @returns Promise with the log response
* @throws {InvalidRequestError} If required fields are missing
* @throws {AuthenticationError} If API keys are invalid
* @throws {NotFoundError} If log is not found
* @throws {ServerError} If server encounters an error
*/
async getLogById(id: number, data: GetLogByIdRequest): Promise<LogResponse> {
this.validateRequiredKeys(data);
try {
return await this.get<LogResponse>(`/${id}`, { 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 === 404) {
throw new NotFoundError(`Log with ID ${id} not found`);
}
if (error.response?.status === 500) {
throw new ServerError('Internal server error');
}
throw error;
}
}
}