Skip to content

Commit 01295dc

Browse files
committed
Initial commit
0 parents  commit 01295dc

12 files changed

+464
-0
lines changed

.babelrc

+3
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": ["es2015"]
3+
}

.gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
/node_modules
2+
/.idea

LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Manuel Fuchs
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# validate-redux-form

lib/index.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.validators = undefined;
7+
exports.validate = validate;
8+
9+
var _lodash = require('lodash.pairs');
10+
11+
var _lodash2 = _interopRequireDefault(_lodash);
12+
13+
var _lodash3 = require('lodash.frompairs');
14+
15+
var _lodash4 = _interopRequireDefault(_lodash3);
16+
17+
var _lodash5 = require('lodash.isfunction');
18+
19+
var _lodash6 = _interopRequireDefault(_lodash5);
20+
21+
var _lodash7 = require('lodash.isobject');
22+
23+
var _lodash8 = _interopRequireDefault(_lodash7);
24+
25+
var _lodash9 = require('lodash.isempty');
26+
27+
var _lodash10 = _interopRequireDefault(_lodash9);
28+
29+
var _validators = require('./validators');
30+
31+
var _validators2 = _interopRequireDefault(_validators);
32+
33+
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
34+
35+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
36+
37+
var validators = exports.validators = _validators2.default;
38+
39+
function validate(data, validationSpec) {
40+
var pairs = (0, _lodash2.default)(validationSpec);
41+
42+
var errorPairs = pairs.reduce(function (acc, pair) {
43+
var key = pair[0];
44+
var value = pair[1];
45+
46+
if ((0, _lodash6.default)(value)) {
47+
var validationResult = value(data[key]);
48+
if (!validationResult) {
49+
return acc;
50+
} else {
51+
return [].concat(_toConsumableArray(acc), [[key, validationResult]]);
52+
}
53+
}
54+
55+
if ((0, _lodash8.default)(value)) {
56+
var _validationResult = validate(data[key] || {}, value);
57+
58+
if ((0, _lodash10.default)(_validationResult)) {
59+
return acc;
60+
} else {
61+
return [].concat(_toConsumableArray(acc), [[key, _validationResult]]);
62+
}
63+
}
64+
65+
return acc;
66+
}, []);
67+
68+
return (0, _lodash4.default)(errorPairs);
69+
}

lib/test.js

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
"use strict";

lib/validators.js

+76
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
'use strict';
2+
3+
Object.defineProperty(exports, "__esModule", {
4+
value: true
5+
});
6+
exports.combine = combine;
7+
8+
function _toConsumableArray(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } else { return Array.from(arr); } }
9+
10+
var validatorFromFunction = exports.validatorFromFunction = function validatorFromFunction(validationFunction) {
11+
return function (params) {
12+
var _this = this;
13+
14+
var argumentsAsArray = [].slice.apply(arguments);
15+
return function (message) {
16+
return function (value) {
17+
return validationFunction.apply(_this, [value].concat(_toConsumableArray(argumentsAsArray))) ? null : message;
18+
};
19+
};
20+
};
21+
};
22+
23+
function combine(validators) {
24+
var _arguments = arguments;
25+
26+
return function (value) {
27+
for (var i = 0; i < _arguments.length; i++) {
28+
var result = _arguments[i](value);
29+
if (result) {
30+
return result;
31+
}
32+
}
33+
34+
return null;
35+
};
36+
}
37+
38+
var exists = exports.exists = validatorFromFunction(function (value) {
39+
return !!value;
40+
});
41+
42+
var length = exports.length = validatorFromFunction(function (string) {
43+
var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
44+
min = _ref.min,
45+
max = _ref.max;
46+
47+
if (min === undefined && max === undefined) {
48+
throw new Error('length requires at least one parameter!');
49+
}
50+
51+
var hasMinLength = min !== undefined ? string.length >= min : true;
52+
var hasMaxLength = max !== undefined ? string.length <= max : true;
53+
return hasMinLength && hasMaxLength;
54+
});
55+
56+
var number = exports.number = validatorFromFunction(function (value) {
57+
var _ref2 = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},
58+
minValue = _ref2.minValue,
59+
maxValue = _ref2.maxValue;
60+
61+
var isNumber = !isNaN(value);
62+
var hasMinValue = minValue !== undefined ? parseInt(value) >= minValue : true;
63+
var hasMaxValue = maxValue !== undefined ? parseInt(value) <= maxValue : true;
64+
return isNumber && hasMinValue && hasMaxValue;
65+
});
66+
67+
var regex = exports.regex = validatorFromFunction(function (value, pattern) {
68+
return value.match(pattern) !== null;
69+
});
70+
71+
exports.default = {
72+
exists: exists,
73+
length: length,
74+
number: number,
75+
regex: regex
76+
};

package.json

+28
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
{
2+
"name": "validate-redux-form",
3+
"version": "0.1.0",
4+
"description": "",
5+
"main": "compiled/index.js",
6+
"scripts": {
7+
"compile": "babel --presets es2015 -d lib/ src/",
8+
"prepublish": "npm run compile",
9+
"test": "npm run compile && mocha --compilers js:babel-core/register"
10+
},
11+
"author": "Manuel Fuchs ([email protected])",
12+
"license": "MIT",
13+
"devDependencies": {
14+
"babel-cli": "^6.24.1",
15+
"babel-core": "^6.24.1",
16+
"babel-preset-es2015": "^6.24.1",
17+
"chai": "^3.5.0",
18+
"mocha": "^3.2.0"
19+
},
20+
"dependencies": {
21+
"lodash": "^4.17.4",
22+
"lodash.frompairs": "^4.0.1",
23+
"lodash.isempty": "^4.4.0",
24+
"lodash.isfunction": "^3.0.8",
25+
"lodash.isobject": "^3.0.2",
26+
"lodash.pairs": "^3.0.1"
27+
}
28+
}

src/index.js

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
import toPairs from 'lodash.pairs'
2+
import fromPairs from 'lodash.frompairs'
3+
import isFunction from 'lodash.isfunction'
4+
import isObject from 'lodash.isobject'
5+
import isEmpty from 'lodash.isempty'
6+
import importedValidators from './validators'
7+
8+
export const validators = importedValidators
9+
10+
export function validate (data, validationSpec) {
11+
const pairs = toPairs(validationSpec)
12+
13+
const errorPairs = pairs.reduce((acc, pair) => {
14+
const key = pair[0]
15+
const value = pair[1]
16+
17+
if (isFunction(value)) {
18+
const validationResult = value(data[key])
19+
if (!validationResult) {
20+
return acc
21+
} else {
22+
return [...acc, [key, validationResult]]
23+
}
24+
}
25+
26+
if (isObject(value)) {
27+
const validationResult = validate(data[key] || {}, value)
28+
29+
if (isEmpty(validationResult)) {
30+
return acc
31+
} else {
32+
return [...acc, [key, validationResult]]
33+
}
34+
}
35+
36+
return acc
37+
}, [])
38+
39+
return fromPairs(errorPairs)
40+
}

src/validators.js

+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
export const validatorFromFunction = (validationFunction) => {
2+
return function (params) {
3+
const argumentsAsArray = [].slice.apply(arguments)
4+
return (message) => (value) => validationFunction.apply(this, [value, ...argumentsAsArray]) ? null : message
5+
}
6+
}
7+
8+
export function combine (validators) {
9+
return (value) => {
10+
for (let i = 0; i < arguments.length; i++) {
11+
const result = arguments[i](value)
12+
if (result) {
13+
return result
14+
}
15+
}
16+
17+
return null
18+
}
19+
}
20+
21+
export const exists = validatorFromFunction(value => !!value)
22+
23+
export const length = validatorFromFunction((string, {min, max} = {}) => {
24+
if (min === undefined && max === undefined) {
25+
throw new Error('length requires at least one parameter!')
26+
}
27+
28+
const hasMinLength = min !== undefined ? string.length >= min : true
29+
const hasMaxLength = max !== undefined ? string.length <= max : true
30+
return hasMinLength && hasMaxLength
31+
})
32+
33+
export const number = validatorFromFunction((value, {minValue, maxValue} = {}) => {
34+
const isNumber = !isNaN(value)
35+
const hasMinValue = minValue !== undefined ? parseInt(value) >= minValue : true
36+
const hasMaxValue = maxValue !== undefined ? parseInt(value) <= maxValue : true
37+
return isNumber && hasMinValue && hasMaxValue
38+
})
39+
40+
export const regex = validatorFromFunction((value, pattern) => value.match(pattern) !== null)
41+
42+
export default {
43+
exists,
44+
length,
45+
number,
46+
regex
47+
}

test/index.spec.js

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
import { expect } from 'chai'
2+
import { validate } from '../src/index'
3+
4+
describe('validate-redux-form', function () {
5+
describe('validate', function () {
6+
it('should be a function', function () {
7+
expect(validate).to.be.a('function')
8+
})
9+
10+
it('should return an object', function () {
11+
expect(validate({}, {})).to.be.an('object')
12+
})
13+
14+
it('should work with a flat object', function () {
15+
const validation = { foo: (value) => 'error' }
16+
expect(validate({}, validation)).to.have.property('foo', 'error')
17+
})
18+
19+
it('should work with a nested object', function () {
20+
const validation = {
21+
foo: (value) => 'error',
22+
bar: {
23+
baz: (value) => 'errorbaz'
24+
}
25+
}
26+
27+
const result = validate({}, validation)
28+
expect(result).to.have.property('foo', 'error')
29+
expect(result).to.have.deep.property('bar.baz', 'errorbaz')
30+
})
31+
32+
it('should omit properties that yield no errors', function () {
33+
const validation = {
34+
foo: (value) => null
35+
}
36+
37+
expect(validate({}, validation)).to.not.have.property('foo')
38+
})
39+
40+
it('should omit nesed objects that contain no errors', function () {
41+
const validation = {
42+
foo: {
43+
bar: (value) => null,
44+
baz: (value) => null
45+
}
46+
}
47+
48+
expect(validate({}, validation)).to.not.have.property('foo')
49+
})
50+
51+
it('should work with deeply nested objects', function () {
52+
const validation = {
53+
foo: {
54+
bar: {
55+
baz: {
56+
qoo: {
57+
quu: {
58+
test: (value) => 'failed'
59+
}
60+
}
61+
}
62+
}
63+
}
64+
}
65+
66+
expect(validate({}, validation)).to.have.deep.property('foo.bar.baz.qoo.quu.test', 'failed')
67+
})
68+
})
69+
})

0 commit comments

Comments
 (0)