export default class APIContract {
static validateResponse(response, schema, logger = null) {
const errors = [];
for (const [field, expectedType] of Object.entries(schema)) {
if (!(field in response)) {
errors.push(`Missing required field: ${field}`);
} else {
const actualType = typeof response[field];
if (actualType !== expectedType) {
errors.push(
`Field '${field}' type mismatch: expected ${expectedType}, got ${actualType}`
);
}
}
}
if (errors.length > 0) {
const message = `API Contract Violation:\n${errors.join('\n')}`;
logger?.error(message);
throw new Error(message);
}
return response;
}
static validateArray(array, itemSchema, logger = null) {
if (!Array.isArray(array)) {
logger?.error('Expected array but got non-array');
throw new Error('Expected array response');
}
return array.map((item, index) => {
try {
return this.validateResponse(item, itemSchema, logger);
} catch (error) {
logger?.error(`Array item ${index} validation failed`, error);
throw error;
}
});
}
}