Skip to content

Commit

Permalink
Merge pull request jquense#105 from grsabreu/master
Browse files Browse the repository at this point in the history
Support custom locale
  • Loading branch information
jquense authored Jul 30, 2017
2 parents 4c7c3f3 + 4f7af6a commit 997dd4a
Show file tree
Hide file tree
Showing 8 changed files with 112 additions and 18 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ json separate from validating it, via the `cast` method.

- [Install](#install)
- [Usage](#usage)
- [Using a custom locale dictionary](#using-a-custom-locale-dictionary)
- [API](#api)
- [`yup`](#yup)
- [`yup.reach(schema: Schema, path: string, value: ?object, context: ?object): Schema`](#yupreachschema-schema-path-string-value-object-context-object-schema)
Expand Down Expand Up @@ -138,6 +139,33 @@ schema.cast({
// => { name: 'jimmy', age: 24, createdOn: Date }
```

### Using a custom locale dictionary
Allows you to customize the default messages used by Yup, when no message is provided with a validation test.
If any message is missing in the custom dictionary the error message will default to Yup's one.
```js
import { setLocale } from 'yup/lib/locale'

setLocale({
mixed: {
default: 'Não é válido',
},
number: {
max: 'Deve ser maior que ${min}',
},
})

// Now use Yup schemas AFTER you defined your custom dicionary
const schema = yup.object().shape({
name: yup.string(),
age: yup.number().min(18),
})
schema.validate({ name: 'jimmy', age: 'hi' })
.catch(function(err){
err.name // 'ValidationError'
err.errors // => ['Deve ser maior que 18']
})
```

## API

### `yup`
Expand Down
17 changes: 17 additions & 0 deletions lib/customLocale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
"use strict";

exports.__esModule = true;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

exports.setLocale = setLocale;
exports.getLocale = getLocale;
var dict = {};

function setLocale(custom) {
return dict = _extends({}, dict, custom);
}

function getLocale() {
return dict;
}
34 changes: 21 additions & 13 deletions lib/locale.js
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
'use strict';

exports.__esModule = true;
var mixed = exports.mixed = {
exports.array = exports.object = exports.boolean = exports.date = exports.number = exports.string = exports.mixed = undefined;

var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; };

var _customLocale = require('./customLocale');

var customLocale = (0, _customLocale.getLocale)();

var mixed = exports.mixed = _extends({
default: '${path} is invalid',
notType: '${path} must be a `${type}` type, got: "${value}" instead',
required: '${path} is a required field',
oneOf: '${path} must be one the following values: ${values}',
notOneOf: '${path} must not be one the following values: ${values}'
};
}, customLocale.mixed);

var string = exports.string = {
var string = exports.string = _extends({
required: '${path} is a required field',
length: '${path} must be exactly ${length} characters',
min: '${path} must be at least ${min} characters',
Expand All @@ -20,32 +28,32 @@ var string = exports.string = {
trim: '${path} must be a trimmed string',
lowercase: '${path} must be a lowercase string',
uppercase: '${path} must be a upper case string'
};
}, customLocale.string);

var number = exports.number = {
var number = exports.number = _extends({
min: '${path} must be greater than or equal to ${min}',
max: '${path} must be less than or equal to ${max}',
positive: '${path} must be a positive number',
negative: '${path} must be a negative number',
integer: '${path} must be an integer'
};
}, customLocale.number);

var date = exports.date = {
var date = exports.date = _extends({
min: '${path} field must be later than ${min}',
max: '${path} field must be at earlier than ${max}'
};
}, customLocale.date);

var boolean = exports.boolean = {};
var boolean = exports.boolean = _extends({}, customLocale.boolean);

var object = exports.object = {
var object = exports.object = _extends({
noUnknown: '${path} field cannot have keys not specified in the object shape'
};
}, customLocale.object);

var array = exports.array = {
var array = exports.array = _extends({
required: '${path} is a required field',
min: '${path} field must have at least ${min} items',
max: '${path} field must have less than ${max} items'
};
}, customLocale.array);

exports.default = {
mixed: mixed,
Expand Down
1 change: 1 addition & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@
},
"dependencies": {
"case": "^1.2.1",
"fn-name": "~1.0.1",
"fn-name": "~1.0.1",
"lodash": "^4.17.0",
"property-expr": "^1.2.0",
"toposort": "^0.2.10",
Expand Down
9 changes: 9 additions & 0 deletions src/customLocale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
let dict = {}

export function setLocale(custom){
return (dict = { ...dict, ...custom })
}

export function getLocale(){
return dict
}
19 changes: 15 additions & 4 deletions src/locale.js
Original file line number Diff line number Diff line change
@@ -1,10 +1,14 @@
import { getLocale } from './customLocale'

const customLocale = getLocale()

export let mixed = {
default: '${path} is invalid',
notType: '${path} must be a `${type}` type, got: "${value}" instead',
required: '${path} is a required field',
oneOf: '${path} must be one the following values: ${values}',
notOneOf: '${path} must not be one the following values: ${values}'
notOneOf: '${path} must not be one the following values: ${values}',
...customLocale.mixed,
}

export let string = {
Expand All @@ -17,7 +21,8 @@ export let string = {
url: '${path} must be a valid URL',
trim: '${path} must be a trimmed string',
lowercase: '${path} must be a lowercase string',
uppercase: '${path} must be a upper case string'
uppercase: '${path} must be a upper case string',
...customLocale.string,
}

export let number = {
Expand All @@ -26,23 +31,29 @@ export let number = {
positive: '${path} must be a positive number',
negative: '${path} must be a negative number',
integer: '${path} must be an integer',
};
...customLocale.number,
}

export let date = {
min: '${path} field must be later than ${min}',
max: '${path} field must be at earlier than ${max}',
...customLocale.date,
}

export let boolean = {};
export let boolean = {
...customLocale.boolean,
};

export let object = {
noUnknown: '${path} field cannot have keys not specified in the object shape',
...customLocale.object,
}

export let array = {
required: '${path} is a required field',
min: '${path} field must have at least ${min} items',
max: '${path} field must have less than ${max} items',
...customLocale.array,
}

export default {
Expand Down
20 changes: 20 additions & 0 deletions test/customLocale.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { setLocale, getLocale } from '../src/customLocale'

describe('Custom locale', () => {
it('should set a new locale', () => {
const dict = {
string: {
email: 'Invalid email',
},
}

setLocale(dict)

expect(getLocale()).to.deep.equal(dict)
})

it('should update the main locale', () => {
const locale = require('../src/locale').default
expect(locale.string).to.deep.include(getLocale().string)
})
})

0 comments on commit 997dd4a

Please sign in to comment.