UNPKG

guardz-event

Version:

Type-safe event handling with runtime validation using guardz for unsafe data from 3rd parties

122 lines 4.36 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.safeEventSourceListener = safeEventSourceListener; const guardz_1 = require("guardz"); const Status_1 = require("../../domain/event/Status"); /** * Safe EventSource event listener with callback-based API * Usage: eventSource.addEventListener('message', safeEventSourceListener(isSSEData, { onSuccess: handleSSEData })); */ function safeEventSourceListener(guard, config) { return (event) => { const result = executeEventSourceValidation(event, { guard, tolerance: config.tolerance, allowedOrigins: config.allowedOrigins, allowedSources: config.allowedSources, onError: (error, context) => { // In tolerance mode, call onTypeMismatch for validation errors if (config.tolerance && context.type === 'validation' && config.onTypeMismatch) { config.onTypeMismatch(error); } else if (config.onError) { config.onError(error, context); } } }); if (result.status === Status_1.Status.SUCCESS) { config.onSuccess(result.data); } else { if (result.code === 500 && config.onTypeMismatch) { config.onTypeMismatch(result.message); } else if (config.onError) { config.onError(result); } } }; } /** * Execute EventSource validation with the given configuration */ function executeEventSourceValidation(event, config) { try { // EventSource specific validation if (event.target instanceof EventSource) { const es = event.target; if (es.readyState === EventSource.CLOSED) { return { status: Status_1.Status.ERROR, code: 500, message: 'EventSource is closed' }; } } // Extract data from EventSource message const data = event.data; // Validate event structure if (config.validateEvent && (typeof data === 'undefined' || data === null)) { const errorMessage = 'EventSource event has no data'; if (config.onError) { config.onError(errorMessage, { type: 'validation', eventType: 'message' }); } return { status: Status_1.Status.ERROR, code: 400, message: errorMessage }; } // Type validation const validationResult = config.tolerance ? (0, guardz_1.guardWithTolerance)(data, config.guard, { identifier: config.identifier || 'EventSource data', callbackOnError: (error) => { if (config.onError) { config.onError(error, { type: 'validation', eventType: 'message' }); } } }) : config.guard(data); if (!validationResult) { const errorMessage = `EventSource data validation failed: ${config.identifier || 'EventSource data'}`; if (config.onError) { config.onError(errorMessage, { type: 'validation', eventType: 'message' }); } return { status: Status_1.Status.ERROR, code: 500, message: errorMessage }; } return { status: Status_1.Status.SUCCESS, data: data }; } catch (error) { const errorMessage = `EventSource validation error: ${error instanceof Error ? error.message : 'Unknown error'}`; if (config.onError) { config.onError(errorMessage, { type: 'unknown', eventType: 'message', originalError: error }); } return { status: Status_1.Status.ERROR, code: 500, message: errorMessage }; } } //# sourceMappingURL=EventSourceListener.js.map