Skip to content

Commit 83b331f

Browse files
author
Rodrigo Solis
committed
feat: includes flow types + fixes sanitazing
1 parent e75c0ca commit 83b331f

File tree

6 files changed

+93
-15
lines changed

6 files changed

+93
-15
lines changed

README.md

+8-4
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ $ npm i proxy-validator
88
```
99

1010
### Usage
11-
The API is fairly simple. Create a validator by providing a validator schema and/or a sanitizing schema.
11+
The API is fairly simple. Create a validator by providing a validation schema and/or a sanitizing schema.
1212
```js
1313
import ProxyValidator from 'proxy-validator';
1414

@@ -18,7 +18,7 @@ const validators = {
1818
name: {
1919
// The key corresponds to a validator function.
2020
isLength: {
21-
// The body can be either an object, containing validating options and errorMessage...
21+
// The value can be either an object, containing options and an errorMessage...
2222
options: {
2323
min: 6
2424
},
@@ -37,12 +37,16 @@ const validators = {
3737
};
3838

3939
const sanitizers = {
40+
// As with the validation, the sanitizing schema is formed by a a key/value pair.
4041
name: {
41-
trim: ' '
42+
// The key corresponds with the sanitizing function
43+
trim: true // and the value can be either boolean (use defaults)
4244
},
4345
email: {
4446
normalizeEmail: {
45-
all_lowercase: true
47+
options: { // ...or a config options object.
48+
all_lowercase: true
49+
}
4650
}
4751
}
4852
};

src/error.js

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
// @flow
2+
import type { ValidationErrors } from './types';
13

2-
function ValidationError(errors) {
4+
function ValidationError(errors: ValidationErrors) {
35
this.name = 'ValidationError';
46
this.message = JSON.stringify(errors, null, ' ');
57
this.stack = new Error().stack;

src/index.js

+40
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,43 @@
11
import ProxyValidator from './proxy';
22

3+
const validators = {
4+
// Define a set of rules to apply for each prop, each rule is formed by a key and a value.
5+
name: {
6+
// The key corresponds to a validator function.
7+
isLength: {
8+
// The value can be either an object, containing options and an errorMessage...
9+
options: {
10+
min: 6
11+
},
12+
errorMessage: 'Minimum length 6 characters.'
13+
},
14+
// ...or a boolean, in which case the message will be the default one.
15+
isUppercase: true
16+
},
17+
mobile: {
18+
isMobilePhone: {
19+
options: 'en-GB',
20+
errorMessage: 'Invalid mobile number.'
21+
},
22+
isAlphanumeric: true
23+
}
24+
};
25+
const sanitizers = {
26+
// As with the validation, the sanitizing schema is formed by a a key/value pair.
27+
name: {
28+
// The key corresponds with the sanitizing function
29+
trim: true // and the value can be either boolean (use defaults)
30+
},
31+
email: {
32+
normalizeEmail: {
33+
options: { // ...or a config options object.
34+
all_lowercase: true
35+
}
36+
}
37+
}
38+
};
39+
const ContactValidator = ProxyValidator(validators, sanitizers);
40+
41+
window.contactTest = ContactValidator();
42+
343
export default ProxyValidator;

src/proxy.js

+8-6
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,23 @@
1+
// @flow
12
/* eslint no-param-reassign: 0 */
23
import ValidationError from './error';
34
import { checkRules, applySanitizers } from './validation';
5+
import type { ProxyFactory } from './types';
46

5-
export default function ProxyValidator(schema, sanitizers) {
7+
export default function ProxyValidator(schema: Object, sanitizersSchema: Object): ProxyFactory {
68
const handler = {
7-
set(object, prop, value) {
9+
set(object: Object, prop: string, value: string): boolean {
810
const { [prop]: rules } = schema;
911
const { success, errors } = checkRules(rules, value);
1012
if (success) {
11-
const { [prop]: transforms } = sanitizers;
12-
object[prop] = applySanitizers(transforms, value);
13+
const { [prop]: sanitizers } = sanitizersSchema;
14+
object[prop] = applySanitizers(sanitizers, value);
1315
return success;
1416
}
15-
throw new ValidationError(errors);
17+
throw new ValidationError({ [prop]: errors });
1618
}
1719
};
18-
return function Proxied() {
20+
return function Proxied(): Object {
1921
const target = {};
2022
return new Proxy(target, handler);
2123
};

src/types.js

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
// @flow
2+
3+
export type ProxyFactory = (void) => Proxy<Object>
4+
5+
export type ValidationErrors = {
6+
[string]: {
7+
value: string,
8+
errorMessage: string
9+
}
10+
};
11+
12+
export type ValidationRule = {
13+
options: ?mixed,
14+
errorMessage: string
15+
};
16+
export type ValidationRules = {
17+
[string]: boolean | ValidationRule
18+
};
19+
20+
export type SanitizingRule = {
21+
options: ?mixed
22+
};
23+
export type SanitizingRules = {
24+
[string]: boolean | SanitizingRule
25+
};

src/validation.js

+9-4
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,32 @@
1+
// @flow
2+
// $FlowFixMe
13
import validator from 'validator';
4+
import type { ValidationRules, SanitizingRules } from './types';
25

36
const GENERIC_ERROR_MESSAGE = 'Invalid input';
47

5-
export function checkRules(rules = {}, value) {
8+
export function checkRules(rules: ValidationRules = {}, value: string) {
69
const errors = [];
710
let success = true;
811
Object.keys(rules)
912
.forEach((rule) => {
1013
const validatorFn = validator[rule];
1114
const config = rules[rule];
12-
const { options, errorMessage = GENERIC_ERROR_MESSAGE } = config;
15+
const options = (typeof config !== 'boolean') && config.options;
16+
const errorMessage = (typeof config !== 'boolean') ? config.errorMessage : GENERIC_ERROR_MESSAGE;
1317
success = validatorFn(value, options);
1418
if (!success) errors.push({ errorMessage, value });
1519
});
1620

1721
return { success, errors };
1822
}
1923

20-
export function applySanitizers(sanitizers = {}, value) {
24+
export function applySanitizers(sanitizers: SanitizingRules = {}, value: mixed): mixed {
2125
return Object.keys(sanitizers)
2226
.reduce((result, sanitizer) => {
2327
const sanitizerFn = validator[sanitizer];
24-
const options = sanitizers[sanitizer];
28+
const config = sanitizers[sanitizer];
29+
const options = (typeof config !== 'boolean') && config.options;
2530
return sanitizerFn(result, options);
2631
}, value) || value;
2732
}

0 commit comments

Comments
 (0)