Skip to content

Instantly share code, notes, and snippets.

@arifmahmudrana
Created January 21, 2020 13:05
Show Gist options
  • Star 7 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save arifmahmudrana/b991f1c15162654b3a481780884c0d4d to your computer and use it in GitHub Desktop.
Save arifmahmudrana/b991f1c15162654b3a481780884c0d4d to your computer and use it in GitHub Desktop.
joi localization internationalization error messages
import { object, string, number, ValidationError } from '@hapi/joi';
const schema = object({
searchCode: string()
.required()
.label('Search code'),
id: number().required()
}),
messages = {
'alternatives.all': '{{#label}} does not match all of the required types',
'alternatives.any': '{{#label}} does not match any of the allowed types',
'alternatives.match': '{{#label}} does not match any of the allowed types',
'alternatives.one': '{{#label}} matches more than one allowed type',
'alternatives.types': '{{#label}} must be one of {{#types}}',
'any.custom':
'{{#label}} failed custom validation because {{#error.message}}',
'any.default': '{{#label}} threw an error when running default method',
'any.failover': '{{#label}} threw an error when running failover method',
'any.invalid': '{{#label}} contains an invalid value',
'any.only':
'{{#label}} must be {if(#valids.length == 1, "", "one of ")}{{#valids}}',
'any.ref': '{{#label}} {{#arg}} references "{{#ref}}" which {{#reason}}',
'any.required': '{{#label}} is required',
'any.unknown': '{{#label}} is not allowed',
'array.base': '{{#label}} must be an array',
'array.excludes': '{{#label}} contains an excluded value',
'array.hasKnown':
'{{#label}} does not contain at least one required match for type "{#patternLabel}"',
'array.hasUnknown':
'{{#label}} does not contain at least one required match',
'array.includes': '{{#label}} does not match any of the allowed types',
'array.includesRequiredBoth':
'{{#label}} does not contain {{#knownMisses}} and {{#unknownMisses}} other required value(s)',
'array.includesRequiredKnowns':
'{{#label}} does not contain {{#knownMisses}}',
'array.includesRequiredUnknowns':
'{{#label}} does not contain {{#unknownMisses}} required value(s)',
'array.length': '{{#label}} must contain {{#limit}} items',
'array.max':
'{{#label}} must contain less than or equal to {{#limit}} items',
'array.min': '{{#label}} must contain at least {{#limit}} items',
'array.orderedLength': '{{#label}} must contain at most {{#limit}} items',
'array.sort': '{{#label}} must be sorted in {#order} order by {{#by}}',
'array.sort.mismatching':
'{{#label}} cannot be sorted due to mismatching types',
'array.sort.unsupported':
'{{#label}} cannot be sorted due to unsupported type {#type}',
'array.sparse': '{{#label}} must not be a sparse array item',
'array.unique': '{{#label}} contains a duplicate value',
'binary.base': '{{#label}} must be a buffer or a string',
'binary.length': '{{#label}} must be {{#limit}} bytes',
'binary.max': '{{#label}} must be less than or equal to {{#limit}} bytes',
'binary.min': '{{#label}} must be at least {{#limit}} bytes',
'boolean.base': '{{#label}} must be a boolean',
'date.base': '{{#label}} must be a valid date',
'date.format':
'{{#label}} must be in {msg("date.format." + #format) || #format} format',
'date.greater': '{{#label}} must be greater than "{{#limit}}"',
'date.less': '{{#label}} must be less than "{{#limit}}"',
'date.max': '{{#label}} must be less than or equal to "{{#limit}}"',
'date.min': '{{#label}} must be larger than or equal to "{{#limit}}"',
// Messages used in date.format
'date.format.iso': 'ISO 8601 date',
'date.format.javascript': 'timestamp or number of milliseconds',
'date.format.unix': 'timestamp or number of seconds',
'function.arity': '{{#label}} must have an arity of {{#n}}',
'function.class': '{{#label}} must be a class',
'function.maxArity':
'{{#label}} must have an arity lesser or equal to {{#n}}',
'function.minArity':
'{{#label}} must have an arity greater or equal to {{#n}}',
'object.and':
'{{#label}} contains {{#presentWithLabels}} without its required peers {{#missingWithLabels}}',
'object.assert':
'{{#label}} is invalid because {if(#subject.key, `"` + #subject.key + `" failed to ` + (#message || "pass the assertion test"), #message || "the assertion failed")}',
'object.base': '{{#label}} must be of type {{#type}}',
'object.instance': '{{#label}} must be an instance of "{{#type}}"',
'object.length':
'{{#label}} must have {{#limit}} key{if(#limit == 1, "", "s")}',
'object.max':
'{{#label}} must have less than or equal to {{#limit}} key{if(#limit == 1, "", "s")}',
'object.min':
'{{#label}} must have at least {{#limit}} key{if(#limit == 1, "", "s")}',
'object.missing':
'{{#label}} must contain at least one of {{#peersWithLabels}}',
'object.nand':
'"{{#mainWithLabel}}" must not exist simultaneously with {{#peersWithLabels}}',
'object.oxor':
'{{#label}} contains a conflict between optional exclusive peers {{#peersWithLabels}}',
'object.pattern.match':
'{{#label}} keys failed to match pattern requirements',
'object.refType': '{{#label}} must be a Joi reference',
'object.regex': '{{#label}} must be a RegExp object',
'object.rename.multiple':
'{{#label}} cannot rename "{{#from}}" because multiple renames are disabled and another key was already renamed to "{{#to}}"',
'object.rename.override':
'{{#label}} cannot rename "{{#from}}" because override is disabled and target "{{#to}}" exists',
'object.schema': '{{#label}} must be a Joi schema of {{#type}} type',
'object.unknown': '{{#label}} is not allowed',
'object.with':
'"{{#mainWithLabel}}" missing required peer "{{#peerWithLabel}}"',
'object.without':
'"{{#mainWithLabel}}" conflict with forbidden peer "{{#peerWithLabel}}"',
'object.xor':
'{{#label}} contains a conflict between exclusive peers {{#peersWithLabels}}',
'number.base': '{{#label}} must be a number',
'number.greater': '{{#label}} must be greater than {{#limit}}',
'number.infinity': '{{#label}} cannot be infinity',
'number.integer': '{{#label}} must be an integer',
'number.less': '{{#label}} must be less than {{#limit}}',
'number.max': '{{#label}} must be less than or equal to {{#limit}}',
'number.min': '{{#label}} must be larger than or equal to {{#limit}}',
'number.multiple': '{{#label}} must be a multiple of {{#multiple}}',
'number.negative': '{{#label}} must be a negative number',
'number.port': '{{#label}} must be a valid port',
'number.positive': '{{#label}} must be a positive number',
'number.precision':
'{{#label}} must have no more than {{#limit}} decimal places',
'number.unsafe': '{{#label}} must be a safe number',
'string.alphanum': '{{#label}} must only contain alpha-numeric characters',
'string.base': '{{#label}} must be a string',
'string.base64': '{{#label}} must be a valid base64 string',
'string.creditCard': '{{#label}} must be a credit card',
'string.dataUri': '{{#label}} must be a valid dataUri string',
'string.domain': '{{#label}} must contain a valid domain name',
'string.email': '{{#label}} must be a valid email',
'string.empty': '{{#label}} is not allowed to be empty',
'string.guid': '{{#label}} must be a valid GUID',
'string.hex': '{{#label}} must only contain hexadecimal characters',
'string.hexAlign':
'{{#label}} hex decoded representation must be byte aligned',
'string.hostname': '{{#label}} must be a valid hostname',
'string.ip': '{{#label}} must be a valid ip address with a {{#cidr}} CIDR',
'string.ipVersion':
'{{#label}} must be a valid ip address of one of the following versions {{#version}} with a {{#cidr}} CIDR',
'string.isoDate': '{{#label}} must be in iso format',
'string.isoDuration': '{{#label}} must be a valid ISO 8601 duration',
'string.length': '{{#label}} length must be {{#limit}} characters long',
'string.lowercase': '{{#label}} must only contain lowercase characters',
'string.max':
'{{#label}} length must be less than or equal to {{#limit}} characters long',
'string.min':
'{{#label}} length must be at least {{#limit}} characters long',
'string.normalize':
'{{#label}} must be unicode normalized in the {{#form}} form',
'string.token':
'{{#label}} must only contain alpha-numeric and underscore characters',
'string.pattern.base':
'{{#label}} with value "{[.]}" fails to match the required pattern: {{#regex}}',
'string.pattern.name':
'{{#label}} with value "{[.]}" fails to match the {{#name}} pattern',
'string.pattern.invert.base':
'{{#label}} with value "{[.]}" matches the inverted pattern: {{#regex}}',
'string.pattern.invert.name':
'{{#label}} with value "{[.]}" matches the inverted {{#name}} pattern',
'string.trim': '{{#label}} must not have leading or trailing whitespace',
'string.uri': '{{#label}} must be a valid uri',
'string.uriCustomScheme':
'{{#label}} must be a valid uri with a scheme matching the {{#scheme}} pattern',
'string.uriRelativeOnly': '{{#label}} must be a valid relative uri',
'string.uppercase': '{{#label}} must only contain uppercase characters',
'symbol.base': '{{#label}} must be a symbol',
'symbol.map': '{{#label}} must be one of {{#map}}'
},
validationResult = schema.validate(
{
id: '1',
primaryContact: {
mobileNumber: '+8801234567890'
},
rooms: [{}]
},
{
abortEarly: true,
allowUnknown: false,
convert: false,
messages
}
);
console.log(validationResult, validationResult.error.details);
if ('isJoi' in validationResult.error) {
console.log('==================This is JOI error==================');
console.log((validationResult.error as ValidationError).annotate());
console.log('==================This is JOI error==================');
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment