verificator
Version:
Client and server-side validation JavaScript library
109 lines (108 loc) • 4.02 kB
JavaScript
import { DEPENDENT_RULES } from './constants';
import * as utils from './utils';
export default class Translator {
constructor(locale, validator) {
this._validator = validator;
this.setLocale(locale);
this.setCustomMessages(locale.customMessages || {});
this.setCustomAttributes(locale.customAttributes || {});
}
setLocale(locale) {
this._messages = utils.flatten(locale.messages);
this._attributes = locale.attributes || {};
return this;
}
getAttribute(attribute) {
const { _attributes, _customAttributes } = this;
if (attribute in _customAttributes) {
return _customAttributes[attribute];
}
if (attribute in _attributes) {
return _attributes[attribute];
}
return null;
}
getMessage(rule, attribute, value, parameters) {
const { _messages, _customMessages } = this;
const rawAttribute = attribute;
attribute = this._getDisplayableAttribute(attribute);
parameters = this._getDisplayableParameters(rule, parameters);
for (let source of [_customMessages, _messages]) {
let message = this._findMessage(source, rawAttribute, { rule, attribute, value, parameters });
if (message !== null) {
return message;
}
}
return `Invalid value for field "${attribute}"`;
}
setCustomMessages(messages) {
this._customMessages = utils.flatten(messages || {});
return this;
}
addCustomMessages(messages) {
this._customMessages = Object.assign({}, this._customMessages, utils.flatten(messages || {}));
return this;
}
setCustomAttributes(attributes) {
this._customAttributes = attributes || {};
return this;
}
addCustomAttributes(attributes) {
this._customAttributes = Object.assign({}, this._customAttributes, (attributes || {}));
return this;
}
_findMessage(source, attribute, parameters) {
const type = this._getAttributeType(attribute);
const keys = [
`${attribute}.${parameters.rule}:${type}`,
`${attribute}.${parameters.rule}`,
`${parameters.rule}:${type}`,
parameters.rule,
];
for (let key of keys) {
for (let sourceKey of Object.keys(source)) {
if (utils.is(sourceKey, key)) {
const message = source[sourceKey];
if (typeof message === 'string') {
return message;
}
if (typeof message === 'function') {
return message(parameters);
}
return null;
}
}
}
return null;
}
_getDisplayableAttribute(attribute) {
const implicitAttributes = this._validator.getImplicitAttributes();
const primaryAttribute = this._validator.getPrimaryAttribute(attribute);
const expectedAttributes = attribute !== primaryAttribute ? [attribute, primaryAttribute] : [attribute];
for (let name of expectedAttributes) {
const line = this.getAttribute(name);
if (line !== null) {
return line;
}
}
if (primaryAttribute in implicitAttributes) {
return attribute;
}
return attribute.toLowerCase().replace(/_/g, ' ');
}
_getDisplayableParameters(rule, parameters) {
if (DEPENDENT_RULES.indexOf(rule) > -1) {
return parameters.map(parameter => this._getDisplayableAttribute(parameter));
}
return parameters;
}
_getAttributeType(attribute) {
if (this._validator.hasRule(attribute, ['numeric', 'integer'])) {
return 'numeric';
}
else if (this._validator.hasRule(attribute, ['array'])) {
return 'array';
}
return 'string';
}
}