@iota-big3/sdk-gateway
Version:
Universal API Gateway with protocol translation, intelligent routing, rate limiting, health checking, and caching
193 lines • 5.76 kB
JavaScript
;
/**
* 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