in src/tsconfig/validator.ts [335:396]
public validate(data: { [field: string]: any }) {
// make sure data is an object
if (!(typeof data === 'object' && !Array.isArray(data) && data !== null)) {
throw new ValidationError([
{ field: this.dataName, message: 'Provided data must be an object, got: ' + JSON.stringify(data) },
]);
}
const checkedFields = new Set();
const violations: Violation[] = [];
// first check all defined rules
for (const rule of this.ruleSet.rules) {
const value = data[rule.field];
// Use a fallback message, but allow the matcher to report a better arrow
let violationMessage = 'Value is not allowed, got: ' + JSON.stringify(value);
const matchResult = rule.matcher(value, {
reporter: (message: string) => {
violationMessage = message;
},
});
switch (rule.type) {
case RuleType.PASS:
if (!matchResult) {
violations.push({
field: rule.field,
message: violationMessage,
});
}
break;
case RuleType.FAIL:
if (matchResult) {
violations.push({
field: rule.field,
message: violationMessage,
});
}
break;
default:
continue;
}
checkedFields.add(rule.field);
}
// finally check fields without any rules if they should fail the validation
if (this.ruleSet.options.unexpectedFields === RuleType.FAIL) {
const receivedFields = Object.keys(data);
for (const field of receivedFields) {
if (!checkedFields.has(field)) {
violations.push({ field: field, message: `Unexpected field, got: ${field}` });
}
}
}
// if we have encountered a violation, throw an error
if (violations.length > 0) {
throw new ValidationError(violations);
}
}