voyage-and-consumption-mcp-server
Version:
Voyage and consumption management server handling vessel voyages, fuel consumption, performance monitoring, and operational data with ERP access for data extraction
164 lines • 5.91 kB
JavaScript
/**
* IMO Validation Utility
*
* Centralizes IMO number validation and parsing logic that was duplicated
* across 13 different tool methods in the codebase.
*
* This utility extracts the common patterns:
* - IMO parameter validation (null/undefined/empty string checks)
* - IMO number parsing with regex validation
* - Standardized error handling for invalid IMO formats
*/
import { logger } from './logger.js';
// Exception class for IMO validation errors
export class MissingParameterError extends Error {
constructor(param, tool_name) {
super(`Missing required parameter '${param}' for tool '${tool_name}'`);
this.param = param;
this.tool_name = tool_name;
}
}
export class InvalidImoError extends Error {
constructor(imo) {
super(`Invalid IMO number format: ${imo}. IMO must be a numeric string.`);
this.imo = imo;
}
}
/**
* Validates that an IMO parameter is present and not empty
* @param imo - The IMO parameter to validate
* @param toolName - The name of the tool calling this validation
* @throws MissingParameterError if IMO is missing or empty
*/
export function validateImoParameter(imo, toolName) {
if (!imo || (typeof imo === 'string' && imo.trim() === "")) {
throw new MissingParameterError("imo", toolName);
}
}
/**
* Validates that an IMO parameter is present (basic check)
* @param imo - The IMO parameter to validate
* @param toolName - The name of the tool calling this validation
* @throws MissingParameterError if IMO is missing
*/
export function validateImoParameterBasic(imo, toolName) {
if (!imo) {
throw new MissingParameterError("imo", toolName);
}
}
/**
* Parses IMO for API methods - returns number if valid numeric string, otherwise original value
* @param imo - The IMO value to parse
* @returns Parsed IMO number or original value
*/
export function parseImoForApi(imo) {
return typeof imo === 'string' && /^\d+$/.test(imo) ? parseInt(imo) : imo;
}
/**
* Parses IMO for database methods - always returns a number
* @param imo - The IMO value to parse
* @returns Parsed IMO number
*/
export function parseImoForDatabase(imo) {
return typeof imo === 'string' && /^\d+$/.test(imo) ? parseInt(imo) : parseInt(String(imo));
}
/**
* Validates and parses IMO for API methods
* @param imo - The IMO parameter to validate and parse
* @param toolName - The name of the tool calling this function
* @returns Parsed IMO number or original value
* @throws MissingParameterError if IMO is missing or empty
*/
export function validateAndParseImoForApi(imo, toolName) {
// For fleet-related tools, only perform basic validation
if (toolName.startsWith('get_fleet_')) {
validateImoParameterBasic(imo, toolName);
const parsedImo = parseImoForApi(imo);
logger.info(`Validated and parsed Fleet IMO for ${toolName}: ${parsedImo}`);
return parsedImo;
}
// For vessel-related tools, perform full validation
validateImoParameter(imo, toolName);
const parsedImo = parseImoForApi(imo);
logger.info(`Validated and parsed IMO for ${toolName}: ${parsedImo}`);
return parsedImo;
}
/**
* Validates and parses IMO for database methods
* @param imo - The IMO parameter to validate and parse
* @param toolName - The name of the tool calling this function
* @returns Parsed IMO number
* @throws MissingParameterError if IMO is missing or empty
*/
export function validateAndParseImoForDatabase(imo, toolName) {
validateImoParameter(imo, toolName);
const parsedImo = parseImoForDatabase(imo);
logger.info(`Validated and parsed IMO for ${toolName}: ${parsedImo}`);
return parsedImo;
}
/**
* Validates and parses IMO for position methods (basic validation)
* @param imo - The IMO parameter to validate
* @param toolName - The name of the tool calling this function
* @returns Original IMO value
* @throws MissingParameterError if IMO is missing
*/
export function validateAndParseImoForPosition(imo, toolName) {
validateImoParameterBasic(imo, toolName);
logger.info(`Validated IMO for ${toolName}: ${imo}`);
return imo;
}
/**
* Validates IMO format using regex (digits only)
* @param imo - The IMO string to validate
* @returns true if IMO contains only digits
*/
export function isValidImoFormat(imo) {
return /^\d+$/.test(imo);
}
/**
* Validates IMO checksum according to IMO standard (DISABLED for demo data compatibility)
* @param _imo - The IMO string to validate (unused)
* @returns true (checksum validation disabled)
*/
export function validateImoChecksum(_imo) {
// Checksum validation disabled to support demo data with non-standard IMO numbers
return true;
}
/**
* Comprehensive IMO validation with checksum
* @param imo - The IMO value to validate
* @param requireChecksum - Whether to validate IMO checksum (default: false)
* @returns true if IMO is valid
*/
export function validateImoFormat(imo, requireChecksum = false) {
if (typeof imo !== 'string') {
return false;
}
if (!isValidImoFormat(imo)) {
return false;
}
if (requireChecksum) {
return validateImoChecksum(imo);
}
return true;
}
/**
* Validates an IMO number and returns validation result with error message
* @param imo - The IMO number to validate
* @returns Object with isValid boolean and error message if invalid
*/
export function validateIMO(imo) {
if (imo === null || imo === undefined) {
return { isValid: false, error: 'IMO number is required' };
}
const imoStr = String(imo);
if (imoStr.trim().length === 0) {
return { isValid: false, error: 'IMO number cannot be empty' };
}
if (!isValidImoFormat(imoStr)) {
return { isValid: false, error: 'IMO number must contain only digits' };
}
return { isValid: true };
}
//# sourceMappingURL=imo-validator.js.map