guardz-event
Version:
Type-safe event handling with runtime validation using guardz for unsafe data from 3rd parties
111 lines • 3.93 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeWebSocketListener = safeWebSocketListener;
const guardz_1 = require("guardz");
const Status_1 = require("../../domain/event/Status");
/**
* Safe WebSocket event listener with callback-based API
* Usage: ws.addEventListener('message', safeWebSocketListener(isWSData, { onSuccess: handleWSData }));
*/
function safeWebSocketListener(guard, config) {
return (event) => {
const result = executeWebSocketValidation(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 WebSocket validation with the given configuration
*/
function executeWebSocketValidation(event, config) {
try {
// Extract data from WebSocket message
const data = event.data;
// Validate event structure
if (config.validateEvent && (typeof data === 'undefined' || data === null)) {
const errorMessage = 'WebSocket 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 || 'WebSocket data',
callbackOnError: (error) => {
if (config.onError) {
config.onError(error, {
type: 'validation',
eventType: 'message'
});
}
}
})
: config.guard(data);
if (!validationResult) {
const errorMessage = `WebSocket data validation failed: ${config.identifier || 'WebSocket 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 = `WebSocket 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=WebSocketListener.js.map