@coxy/react-validator 3.0.0 → 5.0.0
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/biome.json +4 -2
- package/dist/index.js +206 -2
- package/example/example.tsx +19 -51
- package/example/index.html +2 -7
- package/example/tsconfig.json +6 -6
- package/package.json +14 -14
- package/src/context.ts +8 -4
- package/src/index.test.ts +19 -4
- package/src/index.ts +4 -3
- package/src/rules.test.ts +16 -106
- package/src/rules.ts +5 -66
- package/src/types.ts +2 -8
- package/src/use-validator.test.tsx +4 -5
- package/src/use-validator.ts +1 -1
- package/src/validator-field.test.tsx +27 -22
- package/src/validator-field.tsx +37 -54
- package/src/validator-wrapper.test.tsx +36 -18
- package/src/validator-wrapper.tsx +45 -58
- package/src/validator.test.tsx +11 -1
- package/src/validator.ts +25 -20
- package/dist/index.d.mts +0 -116
- package/dist/index.d.ts +0 -116
- package/dist/index.js.map +0 -1
- package/dist/index.mjs +0 -2
- package/dist/index.mjs.map +0 -1
- package/src/jest.d.ts +0 -2
- package/tsup.config.ts +0 -14
package/src/validator.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
+
import type { ZodSafeParseResult } from 'zod'
|
|
1
2
|
import type { ValidatorRules } from './rules'
|
|
2
3
|
import type { FieldParams, Validity } from './types'
|
|
3
4
|
import type { Value } from './validator-field'
|
|
4
5
|
|
|
5
6
|
export class Field {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
protected rules: ValidatorRules
|
|
8
|
+
protected required: boolean
|
|
9
|
+
protected value: Value
|
|
9
10
|
public id: string | number
|
|
10
11
|
|
|
11
12
|
constructor({ rules, required, value, id }: FieldParams) {
|
|
@@ -18,26 +19,31 @@ export class Field {
|
|
|
18
19
|
validate(): Validity {
|
|
19
20
|
let isValid = true
|
|
20
21
|
let message = ''
|
|
21
|
-
const {
|
|
22
|
+
const { value, required, id } = this
|
|
23
|
+
let result: ZodSafeParseResult<unknown> = { success: true, data: value }
|
|
22
24
|
|
|
23
25
|
const isEmptyValue = !value && Number.parseFloat(value) !== 0
|
|
26
|
+
const rules = Array.isArray(this.rules) ? this.rules : [this.rules]
|
|
24
27
|
|
|
25
28
|
if (!rules.length || (isEmptyValue && required === false)) {
|
|
26
|
-
return {
|
|
29
|
+
return {
|
|
30
|
+
isValid,
|
|
31
|
+
message,
|
|
32
|
+
id,
|
|
33
|
+
result: { success: true, data: value },
|
|
34
|
+
}
|
|
27
35
|
}
|
|
28
|
-
for (const
|
|
29
|
-
if (isValid) {
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
message = instance.message
|
|
36
|
-
}
|
|
36
|
+
for (const ruleItem of rules) {
|
|
37
|
+
if (isValid && ruleItem && 'safeParse' in ruleItem) {
|
|
38
|
+
// Handle Zod schemas
|
|
39
|
+
result = ruleItem.safeParse(value)
|
|
40
|
+
isValid = result.success
|
|
41
|
+
if (!isValid && result.error) {
|
|
42
|
+
message = result.error.issues[0]?.message || 'Validation error'
|
|
37
43
|
}
|
|
38
44
|
}
|
|
39
45
|
}
|
|
40
|
-
return { isValid, message, id }
|
|
46
|
+
return { isValid, message, id, result }
|
|
41
47
|
}
|
|
42
48
|
}
|
|
43
49
|
|
|
@@ -79,12 +85,11 @@ export class Validator {
|
|
|
79
85
|
return prevResult
|
|
80
86
|
})
|
|
81
87
|
|
|
82
|
-
const
|
|
88
|
+
const results = statuses.filter((inst) => inst && inst.isValid === false)
|
|
83
89
|
|
|
84
|
-
if (
|
|
85
|
-
|
|
86
|
-
return { isValid, message, errors }
|
|
90
|
+
if (results.length) {
|
|
91
|
+
return results[0]
|
|
87
92
|
}
|
|
88
|
-
return { isValid: true, message: '' }
|
|
93
|
+
return { isValid: true, message: '', result: results[0]?.result }
|
|
89
94
|
}
|
|
90
95
|
}
|
package/dist/index.d.mts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode, Component, RefObject } from 'react';
|
|
3
|
-
|
|
4
|
-
type Value = any;
|
|
5
|
-
type Fn$1 = (validity: Validity, value: Value) => ReactNode;
|
|
6
|
-
interface Props {
|
|
7
|
-
rules?: ValidatorRules;
|
|
8
|
-
required?: boolean;
|
|
9
|
-
value?: Value;
|
|
10
|
-
id?: string | number;
|
|
11
|
-
children?: ReactNode | Fn$1;
|
|
12
|
-
unregisterField: (val: Value) => void;
|
|
13
|
-
registerField: (val: Value) => void;
|
|
14
|
-
customErrors: Array<Validity>;
|
|
15
|
-
}
|
|
16
|
-
declare function ValidatorField(props: Omit<Props, 'registerField' | 'unregisterField' | 'customErrors'>): react_jsx_runtime.JSX.Element;
|
|
17
|
-
|
|
18
|
-
type Fn = (value: Value) => string;
|
|
19
|
-
interface ValidatorRule {
|
|
20
|
-
rule: (value: Value) => boolean;
|
|
21
|
-
message: string | Fn;
|
|
22
|
-
}
|
|
23
|
-
interface ErrorMessage {
|
|
24
|
-
message: string;
|
|
25
|
-
isValid: boolean;
|
|
26
|
-
}
|
|
27
|
-
interface Validity {
|
|
28
|
-
message: string;
|
|
29
|
-
isValid: boolean;
|
|
30
|
-
errors?: ErrorMessage[];
|
|
31
|
-
id?: string | number;
|
|
32
|
-
}
|
|
33
|
-
interface FieldParams {
|
|
34
|
-
value: Value;
|
|
35
|
-
rules: ValidatorRules;
|
|
36
|
-
required?: boolean;
|
|
37
|
-
id?: string | number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
type ValidatorRules = ValidatorRule[];
|
|
41
|
-
declare const rules: {
|
|
42
|
-
notEmpty: {
|
|
43
|
-
rule: (value: any) => boolean;
|
|
44
|
-
message: string;
|
|
45
|
-
}[];
|
|
46
|
-
bool: {
|
|
47
|
-
rule: (value: any) => boolean;
|
|
48
|
-
message: string;
|
|
49
|
-
}[];
|
|
50
|
-
password: {
|
|
51
|
-
rule: (value: any) => boolean;
|
|
52
|
-
message: string;
|
|
53
|
-
}[];
|
|
54
|
-
email: {
|
|
55
|
-
rule: (value: any) => boolean;
|
|
56
|
-
message: string;
|
|
57
|
-
}[];
|
|
58
|
-
min: (min: any) => {
|
|
59
|
-
rule: (value: any) => boolean;
|
|
60
|
-
message: string;
|
|
61
|
-
}[];
|
|
62
|
-
max: (max: any) => {
|
|
63
|
-
rule: (value: any) => boolean;
|
|
64
|
-
message: string;
|
|
65
|
-
}[];
|
|
66
|
-
length: (min: any, max?: any) => {
|
|
67
|
-
rule: (value: any) => boolean;
|
|
68
|
-
message: string;
|
|
69
|
-
}[];
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
declare class Field {
|
|
73
|
-
private rules;
|
|
74
|
-
private required;
|
|
75
|
-
private value;
|
|
76
|
-
id: string | number;
|
|
77
|
-
constructor({ rules, required, value, id }: FieldParams);
|
|
78
|
-
validate(): Validity;
|
|
79
|
-
}
|
|
80
|
-
interface ValidatorParams {
|
|
81
|
-
stopAtFirstError: boolean;
|
|
82
|
-
}
|
|
83
|
-
declare class Validator {
|
|
84
|
-
private fields;
|
|
85
|
-
private params;
|
|
86
|
-
constructor(params?: ValidatorParams);
|
|
87
|
-
addField(params: FieldParams): Field;
|
|
88
|
-
removeField(field: Field): void;
|
|
89
|
-
getField(id: Field['id']): Field;
|
|
90
|
-
validate(): Validity;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
interface ComponentProps {
|
|
94
|
-
children?: ReactNode;
|
|
95
|
-
stopAtFirstError?: boolean;
|
|
96
|
-
ref?: RefObject<ValidatorWrapper>;
|
|
97
|
-
}
|
|
98
|
-
declare class ValidatorWrapper extends Component<ComponentProps> {
|
|
99
|
-
fields: any[];
|
|
100
|
-
state: {
|
|
101
|
-
customErrors: any[];
|
|
102
|
-
};
|
|
103
|
-
constructor(props: any);
|
|
104
|
-
componentWillUnmount(): void;
|
|
105
|
-
registerField(field: any): void;
|
|
106
|
-
unregisterField(field: any): void;
|
|
107
|
-
getField(id: any): Field | null;
|
|
108
|
-
setCustomError(customError: Validity): void;
|
|
109
|
-
clearCustomErrors(): void;
|
|
110
|
-
validate(): Validity;
|
|
111
|
-
render(): ReactNode;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
declare function useValidator(value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>];
|
|
115
|
-
|
|
116
|
-
export { type ErrorMessage, type FieldParams, Validator, ValidatorField, type ValidatorRule, ValidatorWrapper, type Validity, rules, useValidator };
|
package/dist/index.d.ts
DELETED
|
@@ -1,116 +0,0 @@
|
|
|
1
|
-
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { ReactNode, Component, RefObject } from 'react';
|
|
3
|
-
|
|
4
|
-
type Value = any;
|
|
5
|
-
type Fn$1 = (validity: Validity, value: Value) => ReactNode;
|
|
6
|
-
interface Props {
|
|
7
|
-
rules?: ValidatorRules;
|
|
8
|
-
required?: boolean;
|
|
9
|
-
value?: Value;
|
|
10
|
-
id?: string | number;
|
|
11
|
-
children?: ReactNode | Fn$1;
|
|
12
|
-
unregisterField: (val: Value) => void;
|
|
13
|
-
registerField: (val: Value) => void;
|
|
14
|
-
customErrors: Array<Validity>;
|
|
15
|
-
}
|
|
16
|
-
declare function ValidatorField(props: Omit<Props, 'registerField' | 'unregisterField' | 'customErrors'>): react_jsx_runtime.JSX.Element;
|
|
17
|
-
|
|
18
|
-
type Fn = (value: Value) => string;
|
|
19
|
-
interface ValidatorRule {
|
|
20
|
-
rule: (value: Value) => boolean;
|
|
21
|
-
message: string | Fn;
|
|
22
|
-
}
|
|
23
|
-
interface ErrorMessage {
|
|
24
|
-
message: string;
|
|
25
|
-
isValid: boolean;
|
|
26
|
-
}
|
|
27
|
-
interface Validity {
|
|
28
|
-
message: string;
|
|
29
|
-
isValid: boolean;
|
|
30
|
-
errors?: ErrorMessage[];
|
|
31
|
-
id?: string | number;
|
|
32
|
-
}
|
|
33
|
-
interface FieldParams {
|
|
34
|
-
value: Value;
|
|
35
|
-
rules: ValidatorRules;
|
|
36
|
-
required?: boolean;
|
|
37
|
-
id?: string | number;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
type ValidatorRules = ValidatorRule[];
|
|
41
|
-
declare const rules: {
|
|
42
|
-
notEmpty: {
|
|
43
|
-
rule: (value: any) => boolean;
|
|
44
|
-
message: string;
|
|
45
|
-
}[];
|
|
46
|
-
bool: {
|
|
47
|
-
rule: (value: any) => boolean;
|
|
48
|
-
message: string;
|
|
49
|
-
}[];
|
|
50
|
-
password: {
|
|
51
|
-
rule: (value: any) => boolean;
|
|
52
|
-
message: string;
|
|
53
|
-
}[];
|
|
54
|
-
email: {
|
|
55
|
-
rule: (value: any) => boolean;
|
|
56
|
-
message: string;
|
|
57
|
-
}[];
|
|
58
|
-
min: (min: any) => {
|
|
59
|
-
rule: (value: any) => boolean;
|
|
60
|
-
message: string;
|
|
61
|
-
}[];
|
|
62
|
-
max: (max: any) => {
|
|
63
|
-
rule: (value: any) => boolean;
|
|
64
|
-
message: string;
|
|
65
|
-
}[];
|
|
66
|
-
length: (min: any, max?: any) => {
|
|
67
|
-
rule: (value: any) => boolean;
|
|
68
|
-
message: string;
|
|
69
|
-
}[];
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
declare class Field {
|
|
73
|
-
private rules;
|
|
74
|
-
private required;
|
|
75
|
-
private value;
|
|
76
|
-
id: string | number;
|
|
77
|
-
constructor({ rules, required, value, id }: FieldParams);
|
|
78
|
-
validate(): Validity;
|
|
79
|
-
}
|
|
80
|
-
interface ValidatorParams {
|
|
81
|
-
stopAtFirstError: boolean;
|
|
82
|
-
}
|
|
83
|
-
declare class Validator {
|
|
84
|
-
private fields;
|
|
85
|
-
private params;
|
|
86
|
-
constructor(params?: ValidatorParams);
|
|
87
|
-
addField(params: FieldParams): Field;
|
|
88
|
-
removeField(field: Field): void;
|
|
89
|
-
getField(id: Field['id']): Field;
|
|
90
|
-
validate(): Validity;
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
interface ComponentProps {
|
|
94
|
-
children?: ReactNode;
|
|
95
|
-
stopAtFirstError?: boolean;
|
|
96
|
-
ref?: RefObject<ValidatorWrapper>;
|
|
97
|
-
}
|
|
98
|
-
declare class ValidatorWrapper extends Component<ComponentProps> {
|
|
99
|
-
fields: any[];
|
|
100
|
-
state: {
|
|
101
|
-
customErrors: any[];
|
|
102
|
-
};
|
|
103
|
-
constructor(props: any);
|
|
104
|
-
componentWillUnmount(): void;
|
|
105
|
-
registerField(field: any): void;
|
|
106
|
-
unregisterField(field: any): void;
|
|
107
|
-
getField(id: any): Field | null;
|
|
108
|
-
setCustomError(customError: Validity): void;
|
|
109
|
-
clearCustomErrors(): void;
|
|
110
|
-
validate(): Validity;
|
|
111
|
-
render(): ReactNode;
|
|
112
|
-
}
|
|
113
|
-
|
|
114
|
-
declare function useValidator(value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>];
|
|
115
|
-
|
|
116
|
-
export { type ErrorMessage, type FieldParams, Validator, ValidatorField, type ValidatorRule, ValidatorWrapper, type Validity, rules, useValidator };
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rules.ts","../src/context.ts","../src/validator.ts","../src/validator-field.tsx","../src/validator-wrapper.tsx","../src/use-validator.ts"],"names":["emailReg","rules","value","min","max","Context","createContext","Field","required","id","isValid","message","isEmptyValue","instance","Validator","params","field","index","prevResult","errors","inst","ValidationFieldWrapper","Component","props","customError","item","children","validity","ValidatorField","jsx","data","ValidatorWrapper","validator","comp","useValidator","validateObject"],"mappings":"gFAGA,IAAMA,EACJ,wJAIWC,CAAAA,CAAAA,CAAQ,CACnB,QAAU,CAAA,CACR,CACE,IAAOC,CAAAA,CAAAA,EAAUA,CAAU,GAAA,EAAA,EAAMA,EAAM,MAAS,CAAA,CAAA,CAChD,QAAS,mBACX,CACF,EAEA,IAAM,CAAA,CACJ,CACE,IAAA,CAAOA,GAAU,CAAC,CAACA,EACnB,OAAS,CAAA,mBACX,CACF,CAEA,CAAA,QAAA,CAAU,CACR,CACE,IAAA,CAAOA,GAAUA,CAAM,CAAA,MAAA,CAAS,EAChC,OAAS,CAAA,gCACX,EACA,CACE,IAAA,CAAOA,CAAUA,EAAAA,CAAAA,CAAM,OAAS,CAChC,CAAA,OAAA,CAAS,kDACX,CACF,CAAA,CAEA,MAAO,CACL,CACE,KAAOA,CAAU,EAAA,CAAC,CAACA,CAASA,EAAAA,CAAAA,GAAU,IAAMA,CAAM,CAAA,MAAA,GAAW,EAC7D,OAAS,CAAA,mBACX,CACA,CAAA,CACE,KAAOA,CAAUF,EAAAA,CAAAA,CAAS,KAAK,MAAOE,CAAAA,CAAK,EAAE,WAAY,EAAC,EAC1D,OAAS,CAAA,kBACX,CACF,CAEA,CAAA,GAAA,CAAMC,GAAQ,CACZ,CACE,KAAOD,CAAU,EAAA,MAAA,CAAO,UAAWA,CAAAA,CAAK,EAAIC,CAC5C,CAAA,OAAA,CAAS,kCAAkCA,CAAG,CAAA,CAChD,CACF,CAEA,CAAA,GAAA,CAAMC,GAAQ,CACZ,CACE,KAAOF,CAAU,EAAA,MAAA,CAAO,WAAWA,CAAK,CAAA,CAAIE,EAC5C,OAAS,CAAA,CAAA,0BAAA,EAA6BA,CAAG,CAAA,CAC3C,CACF,CAEA,CAAA,MAAA,CAAQ,CAACD,CAAKC,CAAAA,CAAAA,GAAS,CACrB,CACE,IAAA,CAAOF,GAAU,MAAOA,CAAAA,CAAK,EAAE,MAAUC,EAAAA,CAAAA,CACzC,QAAS,CAAgBA,aAAAA,EAAAA,CAAG,UAC9B,CACA,CAAA,CACE,IAAOD,CAAAA,CAAAA,EAAWE,IAAQ,MAAY,CAAA,MAAA,CAAOF,CAAK,CAAE,CAAA,MAAA,EAAUE,EAAM,IACpE,CAAA,OAAA,CAAS,gBAAgBA,CAAG,CAAA,QAAA,CAC9B,CACF,CACF,ECjEO,IAAMC,CAAUC,CAAAA,mBAAAA,CAIpB,IAAI,CCJA,CAAA,IAAMC,EAAN,KAAY,CACT,MACA,QACA,CAAA,KAAA,CACD,GAEP,WAAY,CAAA,CAAE,MAAAN,CAAO,CAAA,QAAA,CAAAO,EAAU,KAAAN,CAAAA,CAAAA,CAAO,EAAAO,CAAAA,CAAG,EAAgB,CACvD,IAAA,CAAK,MAAQR,CACb,CAAA,IAAA,CAAK,SAAWO,CAChB,CAAA,IAAA,CAAK,MAAQN,CACb,CAAA,IAAA,CAAK,GAAKO,EACZ,CAEA,UAAqB,CACnB,IAAIC,EAAU,IACVC,CAAAA,CAAAA,CAAU,EACR,CAAA,CAAE,MAAAV,CAAO,CAAA,KAAA,CAAAC,EAAO,QAAAM,CAAAA,CAAAA,CAAU,GAAAC,CAAG,CAAA,CAAI,KAEjCG,CAAe,CAAA,CAACV,GAAS,MAAO,CAAA,UAAA,CAAWA,CAAK,CAAM,GAAA,CAAA,CAE5D,GAAI,CAACD,CAAAA,CAAM,MAAWW,EAAAA,CAAAA,EAAgBJ,IAAa,KACjD,CAAA,OAAO,CAAE,OAAAE,CAAAA,CAAAA,CAAS,QAAAC,CAAS,CAAA,EAAA,CAAAF,CAAG,CAEhC,CAAA,IAAA,IAAWI,KAAYZ,CACjBS,CAAAA,CAAAA,GACFA,EAAUG,CAAS,CAAA,IAAA,CAAKX,CAAK,CACxBQ,CAAAA,CAAAA,GACC,OAAOG,CAAAA,CAAS,SAAY,UAC9BF,CAAAA,CAAAA,CAAUE,EAAS,OAAQX,CAAAA,CAAK,EAEhCS,CAAUE,CAAAA,CAAAA,CAAS,UAK3B,OAAO,CAAE,QAAAH,CAAS,CAAA,OAAA,CAAAC,EAAS,EAAAF,CAAAA,CAAG,CAChC,CACF,CAAA,CAMaK,CAAN,CAAA,KAAgB,CACb,MACA,CAAA,MAAA,CAER,YAAYC,CAA0B,CAAA,CACpC,KAAK,MAASA,CAAAA,CAAAA,EAAU,KACxB,IAAK,CAAA,MAAA,CAAS,GAChB,CAEA,SAASA,CAA4B,CAAA,CACnC,IAAMC,CAAQ,CAAA,IAAIT,CAAMQ,CAAAA,CAAM,EAC9B,OAAK,IAAA,CAAA,MAAA,CAAO,KAAKC,CAAK,CAAA,CACfA,CACT,CAEA,WAAA,CAAYA,EAAoB,CAC9B,IAAMC,EAAQ,IAAK,CAAA,MAAA,CAAO,QAAQD,CAAK,CAAA,CACnCC,EAAQ,EAAI,EAAA,IAAA,CAAK,MAAO,CAAA,MAAA,CAAOA,EAAO,CAAC,EAC7C,CAEA,QAASR,CAAAA,CAAAA,CAAwB,CAC/B,OAAO,IAAA,CAAK,OAAO,IAAMO,CAAAA,CAAAA,EAAUA,EAAM,EAAOP,GAAAA,CAAE,GAAK,IACzD,CAEA,UAAqB,CACnB,IAAIS,CASEC,CAAAA,CAAAA,CARW,KAAK,MAAO,CAAA,GAAA,CAAKH,GAC5B,IAAK,CAAA,MAAA,EAAQ,kBAAoBE,CAAcA,EAAAA,CAAAA,CAAW,UAAY,KACjE,CAAA,IAAA,EAETA,EAAaF,CAAM,CAAA,QAAA,GACZE,CACR,CAAA,CAAA,CAEuB,OAAQE,CAASA,EAAAA,CAAAA,EAAQA,CAAK,CAAA,OAAA,GAAY,KAAK,CAEvE,CAAA,GAAID,EAAO,MAAQ,CAAA,CACjB,GAAM,CAAE,OAAA,CAAAT,CAAS,CAAA,OAAA,CAAAC,CAAQ,CAAIQ,CAAAA,CAAAA,CAAO,CAAC,CACrC,CAAA,OAAO,CAAE,OAAAT,CAAAA,CAAAA,CAAS,OAAAC,CAAAA,CAAAA,CAAS,OAAAQ,CAAO,CACpC,CACA,OAAO,CAAE,QAAS,IAAM,CAAA,OAAA,CAAS,EAAG,CACtC,CACF,EClEA,IAAME,CAAAA,CAAN,cAAqCC,eAAiB,CACpD,oBAAuB,EAAA,CACrB,KAAK,KAAM,CAAA,eAAA,CAAgB,IAAI,EACjC,CAEA,mBAAoB,CAClB,IAAA,CAAK,MAAM,aAAc,CAAA,IAAI,EAC/B,CAEA,QAAA,EAAqB,CACnB,IAAMC,CAAAA,CAAQ,KAAK,KACbC,CAAAA,CAAAA,CAAcD,CAAM,CAAA,YAAA,CAAa,KAAME,CAASA,EAAAA,CAAAA,CAAK,KAAOF,CAAM,CAAA,EAAE,EAC1E,OAAIC,CAAAA,EAIU,IAAIjB,CAAM,CAAA,CACtB,MAAOgB,CAAM,CAAA,KAAA,CACb,SAAUA,CAAM,CAAA,QAAA,CAChB,MAAOA,CAAM,CAAA,KAAA,CACb,EAAIA,CAAAA,CAAAA,CAAM,EACZ,CAAC,CAAA,CACY,UACf,CAEA,QAAS,CACP,GAAM,CAAE,QAAAG,CAAAA,CAAAA,CAAU,MAAAxB,CAAM,CAAA,CAAI,KAAK,KAC3ByB,CAAAA,CAAAA,CAAW,KAAK,QAAS,EAAA,CAC/B,OAAO,OAAOD,GAAa,UAAaA,CAAAA,CAAAA,CAASC,EAAUzB,CAAK,CAAA,CAAIwB,CACtE,CACF,CAAA,CAEO,SAASE,CAAeL,CAAAA,CAAAA,CAA0E,CACvG,OACEM,cAAAA,CAACxB,EAAQ,QAAR,CAAA,CACE,SAACyB,CACAD,EAAAA,cAAAA,CAACR,CAAA,CAAA,CACE,GAAGE,CACJ,CAAA,YAAA,CAAcO,EAAK,YACnB,CAAA,aAAA,CAAeA,EAAK,aACpB,CAAA,eAAA,CAAiBA,EAAK,eACxB,CAAA,CAAA,CAEJ,CAEJ,CCxDaC,IAAAA,CAAAA,CAAN,cAA+BT,eAA0B,CAC9D,OAAS,EAAC,CACV,MAAQ,CACN,YAAA,CAAc,EAChB,CAAA,CAEA,YAAYC,CAAO,CAAA,CACjB,MAAMA,CAAK,CAAA,CACX,KAAK,aAAgB,CAAA,IAAA,CAAK,aAAc,CAAA,IAAA,CAAK,IAAI,CACjD,CAAA,IAAA,CAAK,gBAAkB,IAAK,CAAA,eAAA,CAAgB,KAAK,IAAI,EACvD,CAEA,oBAAuB,EAAA,CACrB,KAAK,MAAS,CAAA,GAChB,CAEA,aAAA,CAAcP,EAAO,CACfA,CAAAA,EAAS,CAAC,IAAA,CAAK,OAAO,QAASA,CAAAA,CAAK,GACtC,IAAK,CAAA,MAAA,CAAO,KAAKA,CAAK,EAE1B,CAEA,eAAgBA,CAAAA,CAAAA,CAAO,CACrB,IAAMC,CAAAA,CAAQ,KAAK,MAAO,CAAA,OAAA,CAAQD,CAAK,CACnCC,CAAAA,CAAAA,CAAQ,EAAI,EAAA,IAAA,CAAK,OAAO,MAAOA,CAAAA,CAAAA,CAAO,CAAC,EAC7C,CAEA,SAASR,CAAkB,CAAA,CACzB,OAAO,IAAK,CAAA,MAAA,CAAO,KAAMO,CAAUA,EAAAA,CAAAA,CAAM,MAAM,EAAOP,GAAAA,CAAE,GAAK,IAC/D,CAEA,cAAee,CAAAA,CAAAA,CAAuB,CACpC,IAAK,CAAA,QAAA,CAAS,CACZ,YAAc,CAAA,CAAC,GAAG,IAAK,CAAA,KAAA,CAAM,aAAcA,CAAW,CACxD,CAAC,EACH,CAEA,mBAAoB,CAClB,IAAA,CAAK,SAAS,CAAE,YAAA,CAAc,EAAG,CAAC,EACpC,CAEA,UAAqB,CACnB,IAAMQ,EAAY,IAAIlB,CAAAA,CAAU,CAAE,gBAAkB,CAAA,IAAA,CAAK,MAAM,gBAAiB,CAAC,EACjF,IAAWmB,IAAAA,CAAAA,IAAQ,KAAK,MACtBD,CAAAA,CAAAA,CAAU,QAASC,CAAAA,CAAAA,CAAK,KAAK,CAE/B,CAAA,OAAOD,EAAU,QAAS,EAC5B,CAEA,MAAoB,EAAA,CAClB,OACEH,cAACxB,CAAAA,CAAAA,CAAQ,SAAR,CACC,KAAA,CAAO,CACL,YAAc,CAAA,IAAA,CAAK,MAAM,YACzB,CAAA,aAAA,CAAe,IAAK,CAAA,aAAA,CACpB,gBAAiB,IAAK,CAAA,eACxB,EAEC,QAAK,CAAA,IAAA,CAAA,KAAA,CAAM,SACd,CAEJ,CACF,ECrEO,SAAS6B,CAAAA,CAAahC,EAAcD,CAAwE,CAAA,CACjH,IAAM+B,CAAY,CAAA,IAAIlB,EACtBkB,CAAU,CAAA,QAAA,CAAS,CAAE,KAAA,CAAA9B,EAAO,KAAAD,CAAAA,CAAM,CAAC,CACnC,CAAA,GAAM,CAAE,OAAAS,CAAAA,CAAAA,CAAS,GAAGyB,CAAe,CAAA,CAAIH,EAAU,QAAS,EAAA,CAC1D,OAAO,CAACtB,CAAAA,CAASyB,CAAc,CACjC","file":"index.js","sourcesContent":["import type { ValidatorRule } from './types'\n\n// eslint-disable-next-line\nconst emailReg =\n /^(([^<>()\\[\\]\\\\.,;:\\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,}))$/\n\nexport type ValidatorRules = ValidatorRule[]\n\nexport const rules = {\n notEmpty: [\n {\n rule: (value) => value !== '' && value.length > 0,\n message: 'Value is required',\n },\n ],\n\n bool: [\n {\n rule: (value) => !!value,\n message: 'Value is required',\n },\n ],\n\n password: [\n {\n rule: (value) => value.length > 0,\n message: 'Password field cannot be empty',\n },\n {\n rule: (value) => value.length > 5,\n message: 'Password field can not be less than 6 characters',\n },\n ],\n\n email: [\n {\n rule: (value) => !!value && value !== '' && value.length !== 0,\n message: 'Email is required',\n },\n {\n rule: (value) => emailReg.test(String(value).toLowerCase()),\n message: 'Email is invalid',\n },\n ],\n\n min: (min) => [\n {\n rule: (value) => Number.parseFloat(value) > min,\n message: `The value must be greater than ${min}`,\n },\n ],\n\n max: (max) => [\n {\n rule: (value) => Number.parseFloat(value) < max,\n message: `The value must be smaller ${max}`,\n },\n ],\n\n length: (min, max?) => [\n {\n rule: (value) => String(value).length >= min,\n message: `No less than ${min} symbols`,\n },\n {\n rule: (value) => (max !== undefined ? String(value).length <= max : true),\n message: `No more than ${max} symbols`,\n },\n ],\n}\n","import { createContext } from 'react'\n\nimport type { Validity } from './types'\n\nexport const Context = createContext<{\n registerField: (field: string | number) => void\n unregisterField: (field: string | number) => void\n customErrors: Array<Validity>\n}>(null)\n","import type { ValidatorRules } from './rules'\nimport type { FieldParams, Validity } from './types'\nimport type { Value } from './validator-field'\n\nexport class Field {\n private rules: ValidatorRules\n private required: boolean\n private value: Value\n public id: string | number\n\n constructor({ rules, required, value, id }: FieldParams) {\n this.rules = rules\n this.required = required\n this.value = value\n this.id = id\n }\n\n validate(): Validity {\n let isValid = true\n let message = ''\n const { rules, value, required, id } = this\n\n const isEmptyValue = !value && Number.parseFloat(value) !== 0\n\n if (!rules.length || (isEmptyValue && required === false)) {\n return { isValid, message, id }\n }\n for (const instance of rules) {\n if (isValid) {\n isValid = instance.rule(value)\n if (!isValid) {\n if (typeof instance.message === 'function') {\n message = instance.message(value)\n } else {\n message = instance.message\n }\n }\n }\n }\n return { isValid, message, id }\n }\n}\n\nexport interface ValidatorParams {\n stopAtFirstError: boolean\n}\n\nexport class Validator {\n private fields: Field[]\n private params: ValidatorParams\n\n constructor(params?: ValidatorParams) {\n this.params = params || null\n this.fields = []\n }\n\n addField(params: FieldParams): Field {\n const field = new Field(params)\n this.fields.push(field)\n return field\n }\n\n removeField(field: Field): void {\n const index = this.fields.indexOf(field)\n if (index > -1) this.fields.splice(index, 1)\n }\n\n getField(id: Field['id']): Field {\n return this.fields.find((field) => field.id === id) || null\n }\n\n validate(): Validity {\n let prevResult: Validity | null\n const statuses = this.fields.map((field) => {\n if (this.params?.stopAtFirstError && prevResult && prevResult.isValid === false) {\n return null\n }\n prevResult = field.validate()\n return prevResult\n })\n\n const errors = statuses.filter((inst) => inst && inst.isValid === false)\n\n if (errors.length) {\n const { isValid, message } = errors[0]\n return { isValid, message, errors }\n }\n return { isValid: true, message: '' }\n }\n}\n","import { Component, type ReactNode } from 'react'\nimport type { Validity } from 'types'\n\nimport { Context } from './context'\nimport type { ValidatorRules } from './rules'\nimport { Field } from './validator'\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type Value = any\n\ntype Fn = (validity: Validity, value: Value) => ReactNode\n\ninterface Props {\n rules?: ValidatorRules\n required?: boolean\n value?: Value\n id?: string | number\n children?: ReactNode | Fn\n unregisterField: (val: Value) => void\n registerField: (val: Value) => void\n customErrors: Array<Validity>\n}\n\nclass ValidationFieldWrapper extends Component<Props> {\n componentWillUnmount() {\n this.props.unregisterField(this)\n }\n\n componentDidMount() {\n this.props.registerField(this)\n }\n\n validate(): Validity {\n const props = this.props\n const customError = props.customErrors.find((item) => item.id === props.id)\n if (customError) {\n return customError\n }\n\n const field = new Field({\n rules: props.rules,\n required: props.required,\n value: props.value,\n id: props.id,\n })\n return field.validate()\n }\n\n render() {\n const { children, value } = this.props\n const validity = this.validate()\n return typeof children === 'function' ? children(validity, value) : children\n }\n}\n\nexport function ValidatorField(props: Omit<Props, 'registerField' | 'unregisterField' | 'customErrors'>) {\n return (\n <Context.Consumer>\n {(data) => (\n <ValidationFieldWrapper\n {...props}\n customErrors={data.customErrors}\n registerField={data.registerField}\n unregisterField={data.unregisterField}\n />\n )}\n </Context.Consumer>\n )\n}\n","import { Component, type ReactNode, type RefObject } from 'react'\n\nimport { Context } from './context'\nimport type { Validity } from './types'\nimport { type Field, Validator } from './validator'\n\ninterface ComponentProps {\n children?: ReactNode\n stopAtFirstError?: boolean\n ref?: RefObject<ValidatorWrapper>\n}\n\nexport class ValidatorWrapper extends Component<ComponentProps> {\n fields = []\n state = {\n customErrors: [],\n }\n\n constructor(props) {\n super(props)\n this.registerField = this.registerField.bind(this)\n this.unregisterField = this.unregisterField.bind(this)\n }\n\n componentWillUnmount() {\n this.fields = []\n }\n\n registerField(field) {\n if (field && !this.fields.includes(field)) {\n this.fields.push(field)\n }\n }\n\n unregisterField(field) {\n const index = this.fields.indexOf(field)\n if (index > -1) this.fields.splice(index, 1)\n }\n\n getField(id): Field | null {\n return this.fields.find((field) => field.props.id === id) || null\n }\n\n setCustomError(customError: Validity) {\n this.setState({\n customErrors: [...this.state.customErrors, customError],\n })\n }\n\n clearCustomErrors() {\n this.setState({ customErrors: [] })\n }\n\n validate(): Validity {\n const validator = new Validator({ stopAtFirstError: this.props.stopAtFirstError })\n for (const comp of this.fields) {\n validator.addField(comp.props)\n }\n return validator.validate()\n }\n\n render(): ReactNode {\n return (\n <Context.Provider\n value={{\n customErrors: this.state.customErrors,\n registerField: this.registerField,\n unregisterField: this.unregisterField,\n }}\n >\n {this.props.children}\n </Context.Provider>\n )\n }\n}\n","import type { ValidatorRules } from './rules'\nimport type { Validity } from './types'\nimport { Validator } from './validator'\nimport type { Value } from './validator-field'\n\nexport function useValidator(value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>] {\n const validator = new Validator()\n validator.addField({ value, rules })\n const { isValid, ...validateObject } = validator.validate()\n return [isValid, validateObject]\n}\n"]}
|
package/dist/index.mjs
DELETED
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import {createContext,Component}from'react';import {jsx}from'react/jsx-runtime';var h=/^(([^<>()\[\]\\.,;:\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,}))$/,g={notEmpty:[{rule:t=>t!==""&&t.length>0,message:"Value is required"}],bool:[{rule:t=>!!t,message:"Value is required"}],password:[{rule:t=>t.length>0,message:"Password field cannot be empty"},{rule:t=>t.length>5,message:"Password field can not be less than 6 characters"}],email:[{rule:t=>!!t&&t!==""&&t.length!==0,message:"Email is required"},{rule:t=>h.test(String(t).toLowerCase()),message:"Email is invalid"}],min:t=>[{rule:e=>Number.parseFloat(e)>t,message:`The value must be greater than ${t}`}],max:t=>[{rule:e=>Number.parseFloat(e)<t,message:`The value must be smaller ${t}`}],length:(t,e)=>[{rule:r=>String(r).length>=t,message:`No less than ${t} symbols`},{rule:r=>e!==void 0?String(r).length<=e:true,message:`No more than ${e} symbols`}]};var d=createContext(null);var l=class{rules;required;value;id;constructor({rules:e,required:r,value:s,id:i}){this.rules=e,this.required=r,this.value=s,this.id=i;}validate(){let e=true,r="",{rules:s,value:i,required:n,id:m}=this,c=!i&&Number.parseFloat(i)!==0;if(!s.length||c&&n===false)return {isValid:e,message:r,id:m};for(let a of s)e&&(e=a.rule(i),e||(typeof a.message=="function"?r=a.message(i):r=a.message));return {isValid:e,message:r,id:m}}},o=class{fields;params;constructor(e){this.params=e||null,this.fields=[];}addField(e){let r=new l(e);return this.fields.push(r),r}removeField(e){let r=this.fields.indexOf(e);r>-1&&this.fields.splice(r,1);}getField(e){return this.fields.find(r=>r.id===e)||null}validate(){let e,s=this.fields.map(i=>this.params?.stopAtFirstError&&e&&e.isValid===false?null:(e=i.validate(),e)).filter(i=>i&&i.isValid===false);if(s.length){let{isValid:i,message:n}=s[0];return {isValid:i,message:n,errors:s}}return {isValid:true,message:""}}};var u=class extends Component{componentWillUnmount(){this.props.unregisterField(this);}componentDidMount(){this.props.registerField(this);}validate(){let e=this.props,r=e.customErrors.find(i=>i.id===e.id);return r||new l({rules:e.rules,required:e.required,value:e.value,id:e.id}).validate()}render(){let{children:e,value:r}=this.props,s=this.validate();return typeof e=="function"?e(s,r):e}};function F(t){return jsx(d.Consumer,{children:e=>jsx(u,{...t,customErrors:e.customErrors,registerField:e.registerField,unregisterField:e.unregisterField})})}var p=class extends Component{fields=[];state={customErrors:[]};constructor(e){super(e),this.registerField=this.registerField.bind(this),this.unregisterField=this.unregisterField.bind(this);}componentWillUnmount(){this.fields=[];}registerField(e){e&&!this.fields.includes(e)&&this.fields.push(e);}unregisterField(e){let r=this.fields.indexOf(e);r>-1&&this.fields.splice(r,1);}getField(e){return this.fields.find(r=>r.props.id===e)||null}setCustomError(e){this.setState({customErrors:[...this.state.customErrors,e]});}clearCustomErrors(){this.setState({customErrors:[]});}validate(){let e=new o({stopAtFirstError:this.props.stopAtFirstError});for(let r of this.fields)e.addField(r.props);return e.validate()}render(){return jsx(d.Provider,{value:{customErrors:this.state.customErrors,registerField:this.registerField,unregisterField:this.unregisterField},children:this.props.children})}};function x(t,e){let r=new o;r.addField({value:t,rules:e});let{isValid:s,...i}=r.validate();return [s,i]}export{o as Validator,F as ValidatorField,p as ValidatorWrapper,g as rules,x as useValidator};//# sourceMappingURL=index.mjs.map
|
|
2
|
-
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/rules.ts","../src/context.ts","../src/validator.ts","../src/validator-field.tsx","../src/validator-wrapper.tsx","../src/use-validator.ts"],"names":["emailReg","rules","value","min","max","Context","createContext","Field","required","id","isValid","message","isEmptyValue","instance","Validator","params","field","index","prevResult","errors","inst","ValidationFieldWrapper","Component","props","customError","item","children","validity","ValidatorField","jsx","data","ValidatorWrapper","validator","comp","useValidator","validateObject"],"mappings":"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","file":"index.mjs","sourcesContent":["import type { ValidatorRule } from './types'\n\n// eslint-disable-next-line\nconst emailReg =\n /^(([^<>()\\[\\]\\\\.,;:\\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,}))$/\n\nexport type ValidatorRules = ValidatorRule[]\n\nexport const rules = {\n notEmpty: [\n {\n rule: (value) => value !== '' && value.length > 0,\n message: 'Value is required',\n },\n ],\n\n bool: [\n {\n rule: (value) => !!value,\n message: 'Value is required',\n },\n ],\n\n password: [\n {\n rule: (value) => value.length > 0,\n message: 'Password field cannot be empty',\n },\n {\n rule: (value) => value.length > 5,\n message: 'Password field can not be less than 6 characters',\n },\n ],\n\n email: [\n {\n rule: (value) => !!value && value !== '' && value.length !== 0,\n message: 'Email is required',\n },\n {\n rule: (value) => emailReg.test(String(value).toLowerCase()),\n message: 'Email is invalid',\n },\n ],\n\n min: (min) => [\n {\n rule: (value) => Number.parseFloat(value) > min,\n message: `The value must be greater than ${min}`,\n },\n ],\n\n max: (max) => [\n {\n rule: (value) => Number.parseFloat(value) < max,\n message: `The value must be smaller ${max}`,\n },\n ],\n\n length: (min, max?) => [\n {\n rule: (value) => String(value).length >= min,\n message: `No less than ${min} symbols`,\n },\n {\n rule: (value) => (max !== undefined ? String(value).length <= max : true),\n message: `No more than ${max} symbols`,\n },\n ],\n}\n","import { createContext } from 'react'\n\nimport type { Validity } from './types'\n\nexport const Context = createContext<{\n registerField: (field: string | number) => void\n unregisterField: (field: string | number) => void\n customErrors: Array<Validity>\n}>(null)\n","import type { ValidatorRules } from './rules'\nimport type { FieldParams, Validity } from './types'\nimport type { Value } from './validator-field'\n\nexport class Field {\n private rules: ValidatorRules\n private required: boolean\n private value: Value\n public id: string | number\n\n constructor({ rules, required, value, id }: FieldParams) {\n this.rules = rules\n this.required = required\n this.value = value\n this.id = id\n }\n\n validate(): Validity {\n let isValid = true\n let message = ''\n const { rules, value, required, id } = this\n\n const isEmptyValue = !value && Number.parseFloat(value) !== 0\n\n if (!rules.length || (isEmptyValue && required === false)) {\n return { isValid, message, id }\n }\n for (const instance of rules) {\n if (isValid) {\n isValid = instance.rule(value)\n if (!isValid) {\n if (typeof instance.message === 'function') {\n message = instance.message(value)\n } else {\n message = instance.message\n }\n }\n }\n }\n return { isValid, message, id }\n }\n}\n\nexport interface ValidatorParams {\n stopAtFirstError: boolean\n}\n\nexport class Validator {\n private fields: Field[]\n private params: ValidatorParams\n\n constructor(params?: ValidatorParams) {\n this.params = params || null\n this.fields = []\n }\n\n addField(params: FieldParams): Field {\n const field = new Field(params)\n this.fields.push(field)\n return field\n }\n\n removeField(field: Field): void {\n const index = this.fields.indexOf(field)\n if (index > -1) this.fields.splice(index, 1)\n }\n\n getField(id: Field['id']): Field {\n return this.fields.find((field) => field.id === id) || null\n }\n\n validate(): Validity {\n let prevResult: Validity | null\n const statuses = this.fields.map((field) => {\n if (this.params?.stopAtFirstError && prevResult && prevResult.isValid === false) {\n return null\n }\n prevResult = field.validate()\n return prevResult\n })\n\n const errors = statuses.filter((inst) => inst && inst.isValid === false)\n\n if (errors.length) {\n const { isValid, message } = errors[0]\n return { isValid, message, errors }\n }\n return { isValid: true, message: '' }\n }\n}\n","import { Component, type ReactNode } from 'react'\nimport type { Validity } from 'types'\n\nimport { Context } from './context'\nimport type { ValidatorRules } from './rules'\nimport { Field } from './validator'\n\n// biome-ignore lint/suspicious/noExplicitAny: <explanation>\nexport type Value = any\n\ntype Fn = (validity: Validity, value: Value) => ReactNode\n\ninterface Props {\n rules?: ValidatorRules\n required?: boolean\n value?: Value\n id?: string | number\n children?: ReactNode | Fn\n unregisterField: (val: Value) => void\n registerField: (val: Value) => void\n customErrors: Array<Validity>\n}\n\nclass ValidationFieldWrapper extends Component<Props> {\n componentWillUnmount() {\n this.props.unregisterField(this)\n }\n\n componentDidMount() {\n this.props.registerField(this)\n }\n\n validate(): Validity {\n const props = this.props\n const customError = props.customErrors.find((item) => item.id === props.id)\n if (customError) {\n return customError\n }\n\n const field = new Field({\n rules: props.rules,\n required: props.required,\n value: props.value,\n id: props.id,\n })\n return field.validate()\n }\n\n render() {\n const { children, value } = this.props\n const validity = this.validate()\n return typeof children === 'function' ? children(validity, value) : children\n }\n}\n\nexport function ValidatorField(props: Omit<Props, 'registerField' | 'unregisterField' | 'customErrors'>) {\n return (\n <Context.Consumer>\n {(data) => (\n <ValidationFieldWrapper\n {...props}\n customErrors={data.customErrors}\n registerField={data.registerField}\n unregisterField={data.unregisterField}\n />\n )}\n </Context.Consumer>\n )\n}\n","import { Component, type ReactNode, type RefObject } from 'react'\n\nimport { Context } from './context'\nimport type { Validity } from './types'\nimport { type Field, Validator } from './validator'\n\ninterface ComponentProps {\n children?: ReactNode\n stopAtFirstError?: boolean\n ref?: RefObject<ValidatorWrapper>\n}\n\nexport class ValidatorWrapper extends Component<ComponentProps> {\n fields = []\n state = {\n customErrors: [],\n }\n\n constructor(props) {\n super(props)\n this.registerField = this.registerField.bind(this)\n this.unregisterField = this.unregisterField.bind(this)\n }\n\n componentWillUnmount() {\n this.fields = []\n }\n\n registerField(field) {\n if (field && !this.fields.includes(field)) {\n this.fields.push(field)\n }\n }\n\n unregisterField(field) {\n const index = this.fields.indexOf(field)\n if (index > -1) this.fields.splice(index, 1)\n }\n\n getField(id): Field | null {\n return this.fields.find((field) => field.props.id === id) || null\n }\n\n setCustomError(customError: Validity) {\n this.setState({\n customErrors: [...this.state.customErrors, customError],\n })\n }\n\n clearCustomErrors() {\n this.setState({ customErrors: [] })\n }\n\n validate(): Validity {\n const validator = new Validator({ stopAtFirstError: this.props.stopAtFirstError })\n for (const comp of this.fields) {\n validator.addField(comp.props)\n }\n return validator.validate()\n }\n\n render(): ReactNode {\n return (\n <Context.Provider\n value={{\n customErrors: this.state.customErrors,\n registerField: this.registerField,\n unregisterField: this.unregisterField,\n }}\n >\n {this.props.children}\n </Context.Provider>\n )\n }\n}\n","import type { ValidatorRules } from './rules'\nimport type { Validity } from './types'\nimport { Validator } from './validator'\nimport type { Value } from './validator-field'\n\nexport function useValidator(value: Value, rules: ValidatorRules): [boolean, Pick<Validity, 'message' | 'errors'>] {\n const validator = new Validator()\n validator.addField({ value, rules })\n const { isValid, ...validateObject } = validator.validate()\n return [isValid, validateObject]\n}\n"]}
|
package/src/jest.d.ts
DELETED
package/tsup.config.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { defineConfig } from 'tsup'
|
|
2
|
-
|
|
3
|
-
export default defineConfig({
|
|
4
|
-
entry: ['src/index.ts'],
|
|
5
|
-
format: ['cjs', 'esm'],
|
|
6
|
-
target: 'esnext',
|
|
7
|
-
clean: true,
|
|
8
|
-
dts: true,
|
|
9
|
-
treeshake: true,
|
|
10
|
-
splitting: false,
|
|
11
|
-
minify: true,
|
|
12
|
-
sourcemap: true,
|
|
13
|
-
external: ['react'],
|
|
14
|
-
})
|