@martinmilo/verve
Version:
TypeScript domain modeling library with field-level authorization, business rule validation, and context-aware access control
72 lines • 2.85 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.ValidationInitializer = void 0;
const constants_1 = require("../../constants");
const errors_1 = require("../../errors");
const field_1 = require("../../field");
class ValidationInitializer {
static initialize(model, schema) {
const fields = model[constants_1.MODEL_FIELDS]();
const errors = errors_1.VerveErrorList.new();
let modelName;
for (const fieldName of Object.keys(schema)) {
const field = fields[fieldName];
const value = field.unsafeGet();
if (!modelName) {
modelName = field.metadata.model;
}
// Skip validation for uninitialized fields
if (value === undefined) {
continue;
}
// Validate field value
errors.merge(validateField(fieldName, field));
// Set writable and enumerable to true to allow serialization
Object.defineProperty(model, fieldName, {
value,
writable: field.isWritable(),
enumerable: field.isReadable(),
configurable: true,
});
}
if (errors.isPresent()) {
throw new errors_1.VerveError(errors_1.ErrorCode.MODEL_FIELD_VALIDATION_FAILED, {
model: modelName,
errors: errors.toErrorMessagesWithCode().join('\n'),
});
}
}
}
exports.ValidationInitializer = ValidationInitializer;
function validateField(fieldName, fieldInstance) {
const errors = errors_1.VerveErrorList.new();
const fieldMetadata = fieldInstance[constants_1.BOUND_FIELD_METADATA];
const fieldOptions = fieldInstance[constants_1.BOUND_FIELD_OPTIONS];
const fieldValue = fieldInstance.unsafeGet();
// We skip validation for uninitialized fields
if (fieldValue === undefined) {
return errors;
}
// Throw if field is not nullable and value is null
if (fieldValue === null && !fieldOptions.nullable) {
errors.add(errors_1.ErrorCode.FIELD_NOT_NULLABLE, {
field: fieldName,
model: fieldMetadata.model,
});
}
// Validate the field value based on the provided eager validators
const eagerValidators = field_1.Field.getEagerValidators(fieldOptions);
for (const validator of eagerValidators) {
const result = validator(fieldValue);
const validatorName = validator.name || 'anonymous';
if (result !== true) {
errors.add(errors_1.ErrorCode.FIELD_VALIDATOR_FAILED, {
field: fieldName,
validator: validatorName,
model: fieldMetadata.model,
});
}
}
return errors;
}
//# sourceMappingURL=ValidationInitializer.js.map