@coxy/react-validator 1.3.4 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.eslintignore +1 -1
- package/.eslintrc.js +25 -8
- package/CHANGELOG.md +6 -0
- package/README.md +15 -15
- package/babel.config.js +3 -0
- package/dist/context.d.ts +5 -0
- package/dist/context.js +5 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.js +13 -0
- package/dist/rules.d.ts +38 -0
- package/dist/rules.js +43 -0
- package/dist/use-validator.d.ts +3 -0
- package/dist/use-validator.js +22 -0
- package/dist/validator-field.d.ts +25 -0
- package/dist/validator-field.js +33 -0
- package/dist/validator-wrapper.d.ts +17 -0
- package/dist/validator-wrapper.js +42 -0
- package/dist/validator.d.ts +28 -0
- package/dist/validator.js +72 -0
- package/example/example.jsx +29 -26
- package/example/index.html +2 -0
- package/example/webpack.config.js +15 -7
- package/jest.config.ts +10 -0
- package/package.json +34 -27
- package/src/context.test.ts +7 -0
- package/src/context.ts +6 -0
- package/src/index.test.ts +7 -0
- package/src/index.ts +5 -0
- package/src/jest.d.ts +1 -0
- package/src/rules.test.ts +127 -0
- package/src/{rules.js → rules.ts} +26 -15
- package/src/use-validator.test.tsx +58 -0
- package/src/use-validator.ts +10 -0
- package/src/validator-field.test.tsx +161 -0
- package/src/validator-field.tsx +71 -0
- package/src/validator-wrapper.test.tsx +138 -0
- package/src/validator-wrapper.tsx +58 -0
- package/src/validator.test.tsx +30 -0
- package/src/validator.ts +105 -0
- package/tsconfig.build.json +12 -0
- package/tsconfig.json +39 -0
- package/.babelrc.js +0 -14
- package/build/index.js +0 -1
- package/jest.config.js +0 -5
- package/src/context.js +0 -3
- package/src/context.test.js +0 -13
- package/src/index.js +0 -13
- package/src/index.test.js +0 -13
- package/src/rules.test.js +0 -134
- package/src/use-validator.js +0 -8
- package/src/use-validator.test.js +0 -56
- package/src/validator-field.jsx +0 -72
- package/src/validator-field.test.js +0 -190
- package/src/validator-wrapper.jsx +0 -63
- package/src/validator-wrapper.test.js +0 -177
- package/src/validator.js +0 -82
- package/src/validator.test.js +0 -40
- package/webpack.config.js +0 -32
package/.eslintignore
CHANGED
package/.eslintrc.js
CHANGED
|
@@ -1,11 +1,28 @@
|
|
|
1
1
|
module.exports = {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
2
|
+
root: true,
|
|
3
|
+
parser: '@typescript-eslint/parser',
|
|
4
|
+
plugins: [
|
|
5
|
+
'react',
|
|
6
|
+
'import',
|
|
7
|
+
'@typescript-eslint'
|
|
8
|
+
],
|
|
6
9
|
rules: {
|
|
7
|
-
'
|
|
8
|
-
'
|
|
10
|
+
'no-void': [0],
|
|
11
|
+
'react/jsx-tag-spacing': ['error', {
|
|
12
|
+
closingSlash: 'never',
|
|
13
|
+
beforeSelfClosing: 'always',
|
|
14
|
+
afterOpening: 'never',
|
|
15
|
+
beforeClosing: 'never'
|
|
16
|
+
}],
|
|
17
|
+
'import/order': ['error', {
|
|
18
|
+
groups: ['type', 'external', 'internal', 'builtin', 'object', 'index', 'parent', 'sibling'],
|
|
19
|
+
'newlines-between': 'always'
|
|
20
|
+
}]
|
|
9
21
|
},
|
|
10
|
-
extends:
|
|
11
|
-
|
|
22
|
+
extends: [
|
|
23
|
+
'standard',
|
|
24
|
+
'eslint:recommended',
|
|
25
|
+
'plugin:@typescript-eslint/eslint-recommended',
|
|
26
|
+
'plugin:@typescript-eslint/recommended'
|
|
27
|
+
]
|
|
28
|
+
}
|
package/CHANGELOG.md
CHANGED
package/README.md
CHANGED
|
@@ -24,7 +24,7 @@ See more examples [here](example/example.jsx)
|
|
|
24
24
|
|
|
25
25
|
```jsx
|
|
26
26
|
import React, { useState } from 'react';
|
|
27
|
-
import ValidatorWrapper,
|
|
27
|
+
import { ValidatorWrapper, rules, ValidatorField } from '@coxy/react-validator';
|
|
28
28
|
|
|
29
29
|
const validator = React.createRef();
|
|
30
30
|
|
|
@@ -105,21 +105,20 @@ This component has a default set of rules that you can use right away:
|
|
|
105
105
|
|
|
106
106
|
#### ValidatorWrapper props
|
|
107
107
|
|
|
108
|
-
**name** | **default** | **required** | **description**
|
|
109
|
-
|
|
110
|
-
ref | null | no | React\.ref or useRef
|
|
111
|
-
stopAtFirstError | false | no | The validator will stop checking after the first error
|
|
112
|
-
|
|
108
|
+
| **name** | **default** | **required** | **description** |
|
|
109
|
+
|------------------|-------------|--------------|--------------------------------------------------------|
|
|
110
|
+
| ref | null | no | React\.ref or useRef |
|
|
111
|
+
| stopAtFirstError | false | no | The validator will stop checking after the first error |
|
|
113
112
|
|
|
114
113
|
|
|
115
114
|
#### ValidatorField props
|
|
116
115
|
|
|
117
|
-
****name**** | ****default**** | ****required**** | **description**
|
|
118
|
-
|
|
119
|
-
value | undefined | yes | Value for validation
|
|
120
|
-
rules | \[\] | yes | Array of rules for validation
|
|
121
|
-
required | true | no | The field will be required
|
|
122
|
-
id | null | no | ID for get field
|
|
116
|
+
| ****name**** | ****default**** | ****required**** | **description** |
|
|
117
|
+
|--------------|-----------------|------------------|-------------------------------|
|
|
118
|
+
| value | undefined | yes | Value for validation |
|
|
119
|
+
| rules | \[\] | yes | Array of rules for validation |
|
|
120
|
+
| required | true | no | The field will be required |
|
|
121
|
+
| id | null | no | ID for get field |
|
|
123
122
|
|
|
124
123
|
|
|
125
124
|
# React api useValidator
|
|
@@ -136,9 +135,10 @@ console.log(isValid, errors) // false
|
|
|
136
135
|
|
|
137
136
|
#### Validator constructor parameters
|
|
138
137
|
|
|
139
|
-
**name** | **default** | **required** | **description**
|
|
140
|
-
|
|
141
|
-
stopAtFirstError | false | no | The validator will stop checking after the first error
|
|
138
|
+
| **name** | **default** | **required** | **description** |
|
|
139
|
+
|------------------|-------------|--------------|--------------------------------------------------------|
|
|
140
|
+
| stopAtFirstError | false | no | The validator will stop checking after the first error |
|
|
141
|
+
|
|
142
142
|
|
|
143
143
|
#### Validator.addField()
|
|
144
144
|
|
package/babel.config.js
ADDED
package/dist/context.js
ADDED
package/dist/index.d.ts
ADDED
package/dist/index.js
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.useValidator = exports.Validator = exports.ValidatorWrapper = exports.ValidatorField = exports.rules = void 0;
|
|
4
|
+
var rules_1 = require("./rules");
|
|
5
|
+
Object.defineProperty(exports, "rules", { enumerable: true, get: function () { return rules_1.rules; } });
|
|
6
|
+
var validator_field_1 = require("./validator-field");
|
|
7
|
+
Object.defineProperty(exports, "ValidatorField", { enumerable: true, get: function () { return validator_field_1.ValidatorField; } });
|
|
8
|
+
var validator_wrapper_1 = require("./validator-wrapper");
|
|
9
|
+
Object.defineProperty(exports, "ValidatorWrapper", { enumerable: true, get: function () { return validator_wrapper_1.ValidatorWrapper; } });
|
|
10
|
+
var validator_1 = require("./validator");
|
|
11
|
+
Object.defineProperty(exports, "Validator", { enumerable: true, get: function () { return validator_1.Validator; } });
|
|
12
|
+
var use_validator_1 = require("./use-validator");
|
|
13
|
+
Object.defineProperty(exports, "useValidator", { enumerable: true, get: function () { return use_validator_1.useValidator; } });
|
package/dist/rules.d.ts
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { Value } from './validator-field';
|
|
2
|
+
declare type Fn = (value: Value) => string;
|
|
3
|
+
export interface RuleInstance {
|
|
4
|
+
rule: (value: Value) => boolean;
|
|
5
|
+
message: string | Fn;
|
|
6
|
+
}
|
|
7
|
+
export declare type ValidatorRules = RuleInstance[];
|
|
8
|
+
export declare const rules: {
|
|
9
|
+
notEmpty: {
|
|
10
|
+
rule: (value: any) => boolean;
|
|
11
|
+
message: string;
|
|
12
|
+
}[];
|
|
13
|
+
bool: {
|
|
14
|
+
rule: (value: any) => boolean;
|
|
15
|
+
message: string;
|
|
16
|
+
}[];
|
|
17
|
+
password: {
|
|
18
|
+
rule: (value: any) => boolean;
|
|
19
|
+
message: string;
|
|
20
|
+
}[];
|
|
21
|
+
email: {
|
|
22
|
+
rule: (value: any) => boolean;
|
|
23
|
+
message: string;
|
|
24
|
+
}[];
|
|
25
|
+
min: (min: any) => {
|
|
26
|
+
rule: (value: any) => boolean;
|
|
27
|
+
message: string;
|
|
28
|
+
}[];
|
|
29
|
+
max: (max: any) => {
|
|
30
|
+
rule: (value: any) => boolean;
|
|
31
|
+
message: string;
|
|
32
|
+
}[];
|
|
33
|
+
length: (min: any, max?: any) => {
|
|
34
|
+
rule: (value: any) => boolean;
|
|
35
|
+
message: string;
|
|
36
|
+
}[];
|
|
37
|
+
};
|
|
38
|
+
export {};
|
package/dist/rules.js
ADDED
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.rules = void 0;
|
|
4
|
+
const emailReg = /^(([^<>()\[\]\\.,;:\s@"]+(\.[^<>()\[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
|
|
5
|
+
exports.rules = {
|
|
6
|
+
notEmpty: [{
|
|
7
|
+
rule: (value) => value !== '' && value.length > 0,
|
|
8
|
+
message: 'Value is required'
|
|
9
|
+
}],
|
|
10
|
+
bool: [{
|
|
11
|
+
rule: (value) => !!value,
|
|
12
|
+
message: 'Value is required'
|
|
13
|
+
}],
|
|
14
|
+
password: [{
|
|
15
|
+
rule: (value) => value.length > 0,
|
|
16
|
+
message: 'Password field cannot be empty'
|
|
17
|
+
}, {
|
|
18
|
+
rule: (value) => value.length > 5,
|
|
19
|
+
message: 'Password field can not be less than 6 characters'
|
|
20
|
+
}],
|
|
21
|
+
email: [{
|
|
22
|
+
rule: (value) => !!value && value !== '' && value.length !== 0,
|
|
23
|
+
message: 'Email is required'
|
|
24
|
+
}, {
|
|
25
|
+
rule: (value) => emailReg.test(String(value).toLowerCase()),
|
|
26
|
+
message: 'Email is invalid'
|
|
27
|
+
}],
|
|
28
|
+
min: (min) => [{
|
|
29
|
+
rule: (value) => parseFloat(value) > min,
|
|
30
|
+
message: `The value must be greater than ${min}`
|
|
31
|
+
}],
|
|
32
|
+
max: (max) => [{
|
|
33
|
+
rule: (value) => parseFloat(value) < max,
|
|
34
|
+
message: `The value must be smaller ${max}`
|
|
35
|
+
}],
|
|
36
|
+
length: (min, max) => [{
|
|
37
|
+
rule: (value) => String(value).length >= min,
|
|
38
|
+
message: `No less than ${min} symbols`
|
|
39
|
+
}, {
|
|
40
|
+
rule: (value) => (max !== undefined ? String(value).length <= max : true),
|
|
41
|
+
message: `No more than ${max} symbols`
|
|
42
|
+
}]
|
|
43
|
+
};
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __rest = (this && this.__rest) || function (s, e) {
|
|
3
|
+
var t = {};
|
|
4
|
+
for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
|
|
5
|
+
t[p] = s[p];
|
|
6
|
+
if (s != null && typeof Object.getOwnPropertySymbols === "function")
|
|
7
|
+
for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
|
|
8
|
+
if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
|
|
9
|
+
t[p[i]] = s[p[i]];
|
|
10
|
+
}
|
|
11
|
+
return t;
|
|
12
|
+
};
|
|
13
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
14
|
+
exports.useValidator = void 0;
|
|
15
|
+
const validator_1 = require("./validator");
|
|
16
|
+
function useValidator(value, rules) {
|
|
17
|
+
const validator = new validator_1.Validator();
|
|
18
|
+
validator.addField({ value, rules });
|
|
19
|
+
const _a = validator.validate(), { isValid } = _a, validateObject = __rest(_a, ["isValid"]);
|
|
20
|
+
return [isValid, validateObject];
|
|
21
|
+
}
|
|
22
|
+
exports.useValidator = useValidator;
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { ValidatorRules } from './rules';
|
|
3
|
+
export declare type Value = any;
|
|
4
|
+
export interface ErrorMessage {
|
|
5
|
+
message: string;
|
|
6
|
+
isValid: boolean;
|
|
7
|
+
}
|
|
8
|
+
export interface Validity {
|
|
9
|
+
message: string;
|
|
10
|
+
isValid: boolean;
|
|
11
|
+
errors?: ErrorMessage[];
|
|
12
|
+
id?: string | number;
|
|
13
|
+
}
|
|
14
|
+
declare type Fn = (validity: Validity, value: Value) => ReactNode;
|
|
15
|
+
interface Props {
|
|
16
|
+
rules?: ValidatorRules;
|
|
17
|
+
required?: boolean;
|
|
18
|
+
value?: Value;
|
|
19
|
+
id?: string | number;
|
|
20
|
+
children?: ReactNode | Fn;
|
|
21
|
+
unregisterField: (val: any) => void;
|
|
22
|
+
registerField: (val: any) => void;
|
|
23
|
+
}
|
|
24
|
+
export declare function ValidatorField(props: Omit<Props, 'registerField' | 'unregisterField'>): JSX.Element;
|
|
25
|
+
export {};
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidatorField = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const context_1 = require("./context");
|
|
7
|
+
const validator_1 = require("./validator");
|
|
8
|
+
class ValidationFieldWrapper extends react_1.Component {
|
|
9
|
+
componentWillUnmount() {
|
|
10
|
+
this.props.unregisterField(this);
|
|
11
|
+
}
|
|
12
|
+
componentDidMount() {
|
|
13
|
+
this.props.registerField(this);
|
|
14
|
+
}
|
|
15
|
+
validate() {
|
|
16
|
+
const field = new validator_1.Field({
|
|
17
|
+
rules: this.props.rules,
|
|
18
|
+
required: this.props.required,
|
|
19
|
+
value: this.props.value,
|
|
20
|
+
id: this.props.id
|
|
21
|
+
});
|
|
22
|
+
return field.validate();
|
|
23
|
+
}
|
|
24
|
+
render() {
|
|
25
|
+
const { children, value } = this.props;
|
|
26
|
+
const validity = this.validate();
|
|
27
|
+
return (typeof children === 'function' ? children(validity, value) : children);
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
function ValidatorField(props) {
|
|
31
|
+
return ((0, jsx_runtime_1.jsx)(context_1.Context.Consumer, { children: (data) => ((0, jsx_runtime_1.jsx)(ValidationFieldWrapper, Object.assign({}, props, { registerField: data.registerField, unregisterField: data.unregisterField }))) }));
|
|
32
|
+
}
|
|
33
|
+
exports.ValidatorField = ValidatorField;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Component, ReactNode, RefObject } from 'react';
|
|
2
|
+
interface ComponentProps {
|
|
3
|
+
children?: ReactNode;
|
|
4
|
+
stopAtFirstError?: boolean;
|
|
5
|
+
ref?: RefObject<any>;
|
|
6
|
+
}
|
|
7
|
+
export declare class ValidatorWrapper extends Component<ComponentProps> {
|
|
8
|
+
fields: any[];
|
|
9
|
+
constructor(props: any, ctx: any);
|
|
10
|
+
componentWillUnmount(): void;
|
|
11
|
+
registerField(field: any): void;
|
|
12
|
+
unregisterField(field: any): void;
|
|
13
|
+
getField(id: any): any;
|
|
14
|
+
validate(): import("./validator-field").Validity;
|
|
15
|
+
render(): JSX.Element;
|
|
16
|
+
}
|
|
17
|
+
export {};
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidatorWrapper = void 0;
|
|
4
|
+
const jsx_runtime_1 = require("react/jsx-runtime");
|
|
5
|
+
const react_1 = require("react");
|
|
6
|
+
const context_1 = require("./context");
|
|
7
|
+
const validator_1 = require("./validator");
|
|
8
|
+
class ValidatorWrapper extends react_1.Component {
|
|
9
|
+
constructor(props, ctx) {
|
|
10
|
+
super(props, ctx);
|
|
11
|
+
this.fields = [];
|
|
12
|
+
this.registerField = this.registerField.bind(this);
|
|
13
|
+
this.unregisterField = this.unregisterField.bind(this);
|
|
14
|
+
}
|
|
15
|
+
componentWillUnmount() {
|
|
16
|
+
this.fields = [];
|
|
17
|
+
}
|
|
18
|
+
registerField(field) {
|
|
19
|
+
if (field && !this.fields.includes(field)) {
|
|
20
|
+
this.fields.push(field);
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
unregisterField(field) {
|
|
24
|
+
const index = this.fields.indexOf(field);
|
|
25
|
+
if (index > -1)
|
|
26
|
+
this.fields.splice(index, 1);
|
|
27
|
+
}
|
|
28
|
+
getField(id) {
|
|
29
|
+
return this.fields.find((field) => field.props.id === id) || null;
|
|
30
|
+
}
|
|
31
|
+
validate() {
|
|
32
|
+
const validator = new validator_1.Validator({ stopAtFirstError: this.props.stopAtFirstError });
|
|
33
|
+
this.fields.forEach((comp) => {
|
|
34
|
+
validator.addField(comp.props);
|
|
35
|
+
});
|
|
36
|
+
return validator.validate();
|
|
37
|
+
}
|
|
38
|
+
render() {
|
|
39
|
+
return ((0, jsx_runtime_1.jsx)(context_1.Context.Provider, Object.assign({ value: { registerField: this.registerField, unregisterField: this.unregisterField } }, { children: this.props.children })));
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
exports.ValidatorWrapper = ValidatorWrapper;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { Validity, Value } from './validator-field';
|
|
2
|
+
import { ValidatorRules } from './rules';
|
|
3
|
+
export interface FieldParams {
|
|
4
|
+
value: Value;
|
|
5
|
+
rules: ValidatorRules;
|
|
6
|
+
required?: boolean;
|
|
7
|
+
id?: string | number;
|
|
8
|
+
}
|
|
9
|
+
export declare class Field {
|
|
10
|
+
private rules;
|
|
11
|
+
private required;
|
|
12
|
+
private value;
|
|
13
|
+
id: string | number;
|
|
14
|
+
constructor({ rules, required, value, id }: FieldParams);
|
|
15
|
+
validate(): Validity;
|
|
16
|
+
}
|
|
17
|
+
export interface ValidatorParams {
|
|
18
|
+
stopAtFirstError: boolean;
|
|
19
|
+
}
|
|
20
|
+
export declare class Validator {
|
|
21
|
+
private fields;
|
|
22
|
+
private params;
|
|
23
|
+
constructor(params?: ValidatorParams);
|
|
24
|
+
addField(params: FieldParams): Field;
|
|
25
|
+
removeField(field: Field): void;
|
|
26
|
+
getField(id: Field['id']): Field;
|
|
27
|
+
validate(): Validity;
|
|
28
|
+
}
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Validator = exports.Field = void 0;
|
|
4
|
+
class Field {
|
|
5
|
+
constructor({ rules, required, value, id }) {
|
|
6
|
+
this.rules = rules;
|
|
7
|
+
this.required = required;
|
|
8
|
+
this.value = value;
|
|
9
|
+
this.id = id;
|
|
10
|
+
}
|
|
11
|
+
validate() {
|
|
12
|
+
let isValid = true;
|
|
13
|
+
let message = '';
|
|
14
|
+
const { rules, value, required, id } = this;
|
|
15
|
+
const isEmptyValue = !value && parseFloat(value) !== 0;
|
|
16
|
+
if (!rules.length || (isEmptyValue && required === false)) {
|
|
17
|
+
return { isValid, message, id };
|
|
18
|
+
}
|
|
19
|
+
rules.forEach((instance) => {
|
|
20
|
+
if (isValid) {
|
|
21
|
+
isValid = instance.rule(value);
|
|
22
|
+
if (!isValid) {
|
|
23
|
+
if (typeof instance.message === 'function') {
|
|
24
|
+
message = instance.message(value);
|
|
25
|
+
}
|
|
26
|
+
else {
|
|
27
|
+
message = instance.message;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
});
|
|
32
|
+
return { isValid, message, id };
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
exports.Field = Field;
|
|
36
|
+
class Validator {
|
|
37
|
+
constructor(params) {
|
|
38
|
+
this.params = params || null;
|
|
39
|
+
this.fields = [];
|
|
40
|
+
}
|
|
41
|
+
addField(params) {
|
|
42
|
+
const field = new Field(params);
|
|
43
|
+
this.fields.push(field);
|
|
44
|
+
return field;
|
|
45
|
+
}
|
|
46
|
+
removeField(field) {
|
|
47
|
+
const index = this.fields.indexOf(field);
|
|
48
|
+
if (index > -1)
|
|
49
|
+
this.fields.splice(index, 1);
|
|
50
|
+
}
|
|
51
|
+
getField(id) {
|
|
52
|
+
return this.fields.find((field) => field.id === id) || null;
|
|
53
|
+
}
|
|
54
|
+
validate() {
|
|
55
|
+
let prevResult;
|
|
56
|
+
const statuses = this.fields.map((field) => {
|
|
57
|
+
var _a;
|
|
58
|
+
if (((_a = this.params) === null || _a === void 0 ? void 0 : _a.stopAtFirstError) && prevResult && prevResult.isValid === false) {
|
|
59
|
+
return null;
|
|
60
|
+
}
|
|
61
|
+
prevResult = field.validate();
|
|
62
|
+
return prevResult;
|
|
63
|
+
});
|
|
64
|
+
const errors = statuses.filter((inst) => inst && inst.isValid === false);
|
|
65
|
+
if (errors.length) {
|
|
66
|
+
const { isValid, message } = errors[0];
|
|
67
|
+
return { isValid, message, errors };
|
|
68
|
+
}
|
|
69
|
+
return { isValid: true, message: '' };
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
exports.Validator = Validator;
|
package/example/example.jsx
CHANGED
|
@@ -1,45 +1,46 @@
|
|
|
1
1
|
/* eslint no-console: [0] */
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import ValidatorWrapper, { rules, ValidatorField, Validator } from '../src';
|
|
2
|
+
import { useState, createRef } from 'react'
|
|
3
|
+
import { createRoot } from 'react-dom/client'
|
|
5
4
|
|
|
6
|
-
|
|
7
|
-
const [email, setEmail] = useState('');
|
|
8
|
-
const jsxValidator = React.createRef();
|
|
5
|
+
import { ValidatorWrapper, rules, ValidatorField, Validator } from '../dist/index'
|
|
9
6
|
|
|
10
|
-
|
|
11
|
-
|
|
7
|
+
function App () {
|
|
8
|
+
const [email, setEmail] = useState('')
|
|
9
|
+
const jsxValidator = createRef()
|
|
10
|
+
|
|
11
|
+
function handleValidateEmail () {
|
|
12
|
+
const { isValid, message, errors } = jsxValidator.current.validate()
|
|
12
13
|
if (!isValid) {
|
|
13
|
-
console.log(isValid, message, errors)
|
|
14
|
-
return
|
|
14
|
+
console.log(isValid, message, errors)
|
|
15
|
+
return
|
|
15
16
|
}
|
|
16
|
-
console.log('success')
|
|
17
|
+
console.log('success')
|
|
17
18
|
}
|
|
18
19
|
|
|
19
|
-
function handleValidateCustomFields() {
|
|
20
|
-
const validator = new Validator({ stopAtFirstError: true })
|
|
20
|
+
function handleValidateCustomFields () {
|
|
21
|
+
const validator = new Validator({ stopAtFirstError: true })
|
|
21
22
|
const fieldPassword = validator.addField({
|
|
22
23
|
rules: rules.password,
|
|
23
24
|
value: '',
|
|
24
|
-
id: 'for-remove'
|
|
25
|
-
})
|
|
25
|
+
id: 'for-remove'
|
|
26
|
+
})
|
|
26
27
|
|
|
27
|
-
const fieldSearchPassword = validator.getField('for-remove')
|
|
28
|
-
console.log(fieldPassword === fieldSearchPassword)
|
|
28
|
+
const fieldSearchPassword = validator.getField('for-remove')
|
|
29
|
+
console.log(fieldPassword === fieldSearchPassword)
|
|
29
30
|
|
|
30
|
-
validator.removeField(fieldPassword)
|
|
31
|
+
validator.removeField(fieldPassword)
|
|
31
32
|
|
|
32
33
|
validator.addField({
|
|
33
34
|
rules: rules.password,
|
|
34
|
-
value: 'testpassword'
|
|
35
|
-
})
|
|
35
|
+
value: 'testpassword'
|
|
36
|
+
})
|
|
36
37
|
|
|
37
|
-
const { isValid, message, errors } = validator.validate()
|
|
38
|
+
const { isValid, message, errors } = validator.validate()
|
|
38
39
|
if (!isValid) {
|
|
39
|
-
console.log(isValid, message, errors)
|
|
40
|
-
return
|
|
40
|
+
console.log(isValid, message, errors)
|
|
41
|
+
return
|
|
41
42
|
}
|
|
42
|
-
console.log('success')
|
|
43
|
+
console.log('success')
|
|
43
44
|
}
|
|
44
45
|
|
|
45
46
|
return (
|
|
@@ -58,7 +59,9 @@ function App() {
|
|
|
58
59
|
<button onClick={handleValidateCustomFields} type="button">Validate custom fields</button>
|
|
59
60
|
</ValidatorWrapper>
|
|
60
61
|
</>
|
|
61
|
-
)
|
|
62
|
+
)
|
|
62
63
|
}
|
|
63
64
|
|
|
64
|
-
|
|
65
|
+
const root = createRoot(document.getElementById('root'))
|
|
66
|
+
|
|
67
|
+
root.render(<App />)
|
package/example/index.html
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
<head>
|
|
4
4
|
<meta charset="UTF-8">
|
|
5
5
|
<title>Test template</title>
|
|
6
|
+
<script crossorigin src="https://unpkg.com/react@18/umd/react.development.js"></script>
|
|
7
|
+
<script crossorigin src="https://unpkg.com/react-dom@18/umd/react-dom.development.js"></script>
|
|
6
8
|
</head>
|
|
7
9
|
<body>
|
|
8
10
|
|
|
@@ -1,21 +1,29 @@
|
|
|
1
|
-
|
|
1
|
+
// eslint-disable-next-line @typescript-eslint/no-var-requires
|
|
2
|
+
const path = require('path')
|
|
2
3
|
|
|
3
4
|
module.exports = {
|
|
5
|
+
target: 'web',
|
|
4
6
|
entry: [
|
|
5
|
-
path.resolve('./example/example.jsx')
|
|
7
|
+
path.resolve('./example/example.jsx')
|
|
6
8
|
],
|
|
9
|
+
mode: 'development',
|
|
7
10
|
output: {
|
|
8
11
|
path: path.resolve('./example'),
|
|
9
|
-
filename: './dist/example.js'
|
|
12
|
+
filename: './dist/example.js'
|
|
10
13
|
},
|
|
14
|
+
devtool: 'source-map',
|
|
11
15
|
module: {
|
|
12
16
|
rules: [{
|
|
13
17
|
test: /\.jsx?$/,
|
|
14
18
|
exclude: /node_modules/,
|
|
15
|
-
loader: 'babel-loader'
|
|
16
|
-
}]
|
|
19
|
+
loader: 'babel-loader'
|
|
20
|
+
}]
|
|
17
21
|
},
|
|
18
22
|
resolve: {
|
|
19
|
-
extensions: ['.js', '.jsx']
|
|
23
|
+
extensions: ['.js', '.jsx']
|
|
20
24
|
},
|
|
21
|
-
|
|
25
|
+
externals: {
|
|
26
|
+
react: 'React',
|
|
27
|
+
'react-dom': 'ReactDOM'
|
|
28
|
+
}
|
|
29
|
+
}
|
package/jest.config.ts
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/** @type {import('ts-jest/dist/types').InitialOptionsTsJest} */
|
|
2
|
+
globalThis.IS_REACT_ACT_ENVIRONMENT = true
|
|
3
|
+
|
|
4
|
+
export default {
|
|
5
|
+
preset: 'ts-jest',
|
|
6
|
+
testEnvironment: 'node',
|
|
7
|
+
collectCoverage: true,
|
|
8
|
+
coverageDirectory: './coverage/',
|
|
9
|
+
displayName: '@coxy'
|
|
10
|
+
}
|