UNPKG

@iota-big3/sdk-gateway

Version:

Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching

193 lines 5.76 kB
"use strict"; /** * Validation utilities and type guards for gateway data */ Object.defineProperty(exports, "__esModule", { value: true }); exports.isGatewayRequest = isGatewayRequest; exports.isProtocol = isProtocol; exports.isServiceEndpoint = isServiceEndpoint; exports.isRouteConfig = isRouteConfig; exports.isDiscoveredService = isDiscoveredService; exports.isHealthCheckResult = isHealthCheckResult; exports.validateGatewayRequest = validateGatewayRequest; exports.validateDiscoveredService = validateDiscoveredService; exports.createGatewayResponse = createGatewayResponse; exports.createErrorResponse = createErrorResponse; /** * Type guard for GatewayRequest */ function isGatewayRequest(value) { if (!value || typeof value !== 'object') { return false; } const req = value; return (typeof req.id === 'string' && typeof req.method === 'string' && typeof req.path === 'string' && typeof req.protocol === 'string' && isProtocol(req.protocol) && typeof req.headers === 'object' && req.headers !== null); } /** * Type guard for Protocol */ function isProtocol(value) { return (typeof value === 'string' && ['http', 'https', 'grpc', 'websocket', 'graphql'].includes(value)); } /** * Type guard for ServiceEndpoint */ function isServiceEndpoint(value) { if (!value || typeof value !== 'object') { return false; } const endpoint = value; return (typeof endpoint.id === 'string' && typeof endpoint.url === 'string' && typeof endpoint.protocol === 'string' && isProtocol(endpoint.protocol) && (endpoint.weight === undefined || typeof endpoint.weight === 'number')); } /** * Type guard for RouteConfig */ function isRouteConfig(value) { if (!value || typeof value !== 'object') { return false; } const route = value; return (typeof route.id === 'string' && typeof route.path === 'string' && Array.isArray(route.endpoints) && route.endpoints.every(isServiceEndpoint)); } /** * Type guard for DiscoveredService */ function isDiscoveredService(value) { if (!value || typeof value !== 'object') { return false; } const service = value; return (typeof service.id === 'string' && typeof service.name === 'string' && typeof service.host === 'string' && typeof service.port === 'number' && service.lastSeen instanceof Date); } /** * Type guard for HealthCheckResult */ function isHealthCheckResult(value) { if (!value || typeof value !== 'object') { return false; } const result = value; return (typeof result.serviceId === 'string' && typeof result.status === 'string' && ['healthy', 'unhealthy', 'degraded'].includes(result.status) && (result.error === undefined || typeof result.error === 'string') && (result.latency === undefined || typeof result.latency === 'number')); } /** * Validates and sanitizes external gateway request data */ function validateGatewayRequest(data) { if (!isGatewayRequest(data)) { return null; } // Additional validation/sanitization const sanitized = { id: data.id.trim(), method: data.method.toUpperCase(), path: sanitizePath(data.path), protocol: data.protocol, headers: sanitizeHeaders(data.headers), body: data.body, query: data.query }; return sanitized; } /** * Validates service discovery data from external sources */ function validateDiscoveredService(data) { if (!data || typeof data !== 'object') { return null; } const service = data; // Required fields if (typeof service.id !== 'string' || typeof service.name !== 'string' || typeof service.host !== 'string' || typeof service.port !== 'number') { return null; } // Create valid DiscoveredService return { id: service.id.trim(), name: service.name.trim(), host: service.host.trim(), port: Math.floor(service.port), lastSeen: new Date(), version: typeof service.version === 'string' ? service.version : undefined, metadata: service.metadata, healthCheck: typeof service.healthCheck === 'string' ? service.healthCheck : undefined, endpoints: Array.isArray(service.endpoints) ? service.endpoints.filter(isServiceEndpoint) : undefined }; } /** * Sanitizes URL path */ function sanitizePath(path) { // Remove double slashes, trailing slashes (except root) return path .replace(/\/+/g, '/') .replace(/\/$/, '') .trim() || '/'; } /** * Sanitizes headers object */ function sanitizeHeaders(headers) { const sanitized = {}; for (const [key, value] of Object.entries(headers)) { if (typeof value === 'string') { sanitized[key.toLowerCase()] = value; } else if (Array.isArray(value)) { sanitized[key.toLowerCase()] = value.filter(v => typeof v === 'string'); } } return sanitized; } /** * Creates a type-safe API response */ function createGatewayResponse(data, status = 200, headers = {}) { return { statusCode: status, headers: { 'content-type': 'application/json', ...headers }, body: data }; } /** * Creates a type-safe error response */ function createErrorResponse(message, status = 500, code) { return createGatewayResponse({ error: { message, code: code || 'GATEWAY_ERROR', timestamp: new Date().toISOString() } }, status); } //# sourceMappingURL=validation.js.map