guardz-event
Version:
Type-safe event handling with runtime validation using guardz for unsafe data from 3rd parties
126 lines • 4.49 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.safeDOMEventListener = safeDOMEventListener;
const guardz_1 = require("guardz");
const Status_1 = require("../../domain/event/Status");
/**
* Safe DOM event listener with callback-based API
* Usage: element.addEventListener('click', safeDOMEventListener(isClickData, { onSuccess: handleClick }));
*/
function safeDOMEventListener(guard, config) {
return (event) => {
const result = executeDOMEventValidation(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 DOM event validation with the given configuration
*/
function executeDOMEventValidation(event, config) {
try {
// Handle null/undefined events
if (!event) {
const errorMessage = 'Invalid event: Event is null or undefined';
if (config.onError) {
config.onError(errorMessage, {
type: 'unknown',
eventType: 'unknown'
});
}
return {
status: Status_1.Status.ERROR,
code: 400,
message: errorMessage
};
}
// Extract data from DOM event
const data = event;
// Validate event structure
if (config.validateEvent && (typeof data === 'undefined' || data === null)) {
const errorMessage = 'DOM event has no data';
if (config.onError) {
config.onError(errorMessage, {
type: 'validation',
eventType: event.type || 'unknown'
});
}
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 || `DOM event (${event.type || 'unknown'})`,
callbackOnError: (error) => {
if (config.onError) {
config.onError(error, {
type: 'validation',
eventType: event.type || 'unknown'
});
}
}
})
: config.guard(data);
if (!validationResult) {
const errorMessage = `DOM event validation failed: ${config.identifier || `DOM event (${event.type || 'unknown'})`}`;
if (config.onError) {
config.onError(errorMessage, {
type: 'validation',
eventType: event.type || 'unknown'
});
}
return {
status: Status_1.Status.ERROR,
code: 500,
message: errorMessage
};
}
return {
status: Status_1.Status.SUCCESS,
data: data
};
}
catch (error) {
const errorMessage = `DOM event validation error: ${error instanceof Error ? error.message : 'Unknown error'}`;
if (config.onError) {
config.onError(errorMessage, {
type: 'unknown',
eventType: event?.type || 'unknown',
originalError: error
});
}
return {
status: Status_1.Status.ERROR,
code: 500,
message: errorMessage
};
}
}
//# sourceMappingURL=DOMEventListener.js.map