Skip to content

Commit 08fc1a7

Browse files
authored
Merge pull request #3 from SecJS/feat/len-lkp-new-props
Feat/len lkp new props
2 parents e90e4f7 + 2c65453 commit 08fc1a7

9 files changed

Lines changed: 295 additions & 65 deletions

File tree

README.md

Lines changed: 113 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -36,18 +36,18 @@ npm install @secjs/validator
3636

3737
> Use Validator class to extend in your validation classes
3838
39-
```js
39+
```ts
4040
import { Validator } from '@secjs/validator'
4141

4242
export class UserValidator extends Validator {
43-
createSchema() {
43+
get schema() {
4444
return {
4545
name: 'string|required',
4646
email: 'email|required',
4747
}
4848
}
4949

50-
updateSchema() {
50+
get updateSchema() {
5151
return {
5252
name: 'string',
5353
email: 'string',
@@ -57,8 +57,109 @@ export class UserValidator extends Validator {
5757

5858
const userValidator = new UserValidator()
5959

60-
userValidator.validate({ name: 'João', email: 'lenonSec7@gmail.com' }, 'createSchema') // Return on first error or undefined
61-
userValidator.validateAll({ name: 'João', email: 'lenonSec7@gmail.com' }, 'updateSchema') // Return all errors or undefined
60+
try {
61+
const validatedData = await userValidator.validate({
62+
name: 'João',
63+
email: 'lenonSec7@gmail.com'
64+
}, 'schema')
65+
66+
return validatedData
67+
} catch(error) {
68+
// All the validation errors found
69+
throw error
70+
}
71+
```
72+
73+
### Nice validator options
74+
75+
> Fail on first and clean the data
76+
77+
```ts
78+
import { Validator } from '@secjs/validator'
79+
80+
export class UserValidator extends Validator {
81+
get validateAll() {
82+
return false
83+
}
84+
85+
get removeAdditional() {
86+
return true
87+
}
88+
89+
get schema() {
90+
return {
91+
name: 'string|required',
92+
email: 'email|required',
93+
}
94+
}
95+
}
96+
97+
const userValidator = new UserValidator()
98+
99+
try {
100+
const validatedData = await userValidator.validate({
101+
name: 'João',
102+
email: 'lenonSec7@gmail.com',
103+
additionalProp: 'hello'
104+
}, 'schema')
105+
106+
return validatedData // { name: 'João', email: 'lenonSec7@gmail.com' } without additionalProp
107+
} catch(error) {
108+
// Only the first validation error found
109+
throw error
110+
// [
111+
// {
112+
// message: 'required validation failed on name',
113+
// validation: 'required',
114+
// field: 'name',
115+
// }
116+
// ]
117+
}
118+
```
119+
120+
### Custom error messages
121+
122+
> Use custom error messages and Internationalization support
123+
124+
```ts
125+
import { Validator } from '@secjs/validator'
126+
127+
export class UserValidator extends Validator {
128+
get messages() {
129+
return {
130+
email: '{{ field }} is not a valid email',
131+
// pt-br
132+
'name.required': '{{ field }} é obrigatório para criar um usuário'
133+
}
134+
}
135+
136+
get schema() {
137+
return {
138+
name: 'string|required',
139+
email: 'email|required',
140+
}
141+
}
142+
}
143+
144+
const userValidator = new UserValidator()
145+
146+
try {
147+
// try implementation...
148+
} catch(error) {
149+
throw error
150+
// [
151+
// {
152+
// message: 'name é obrigatório para criar um usuário',
153+
// validation: 'required',
154+
// field: 'name',
155+
// },
156+
// {
157+
// message: 'email is not a valid email',
158+
// validation: 'email',
159+
// field: 'email',
160+
// }
161+
// ]
162+
}
62163
```
63164

64165
## Sanitizer
@@ -69,22 +170,24 @@ userValidator.validateAll({ name: 'João', email: 'lenonSec7@gmail.com' }, 'upda
69170
import { Sanitizer } from '@secjs/validator'
70171

71172
export class UserSanitizer extends Sanitizer {
72-
createSchema() {
173+
get schema() {
73174
return {
74-
email: 'trim',
175+
email: 'trim|lower_case',
75176
}
76177
}
77178

78-
updateSchema() {
179+
get updateSchema() {
79180
return {
80-
email: 'trim',
181+
email: 'trim|lower_case',
81182
}
82183
}
83184
}
84185

85186
const userSanitizer = new UserSanitizer()
86187

87-
userSanitizer.sanitize({ email: 'lenonSec7@gmail.com' }, 'createSchema') // Return the object with sanitizations implemented
188+
userSanitizer.sanitize({
189+
email: 'lenonSec7@gmail.com '
190+
}, 'schema') // Return the object with sanitizations implemented
88191
// { email: 'lenonsec7@gmail.com' }
89192
```
90193

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@secjs/validator",
3-
"version": "1.0.0",
3+
"version": "1.0.1",
44
"license": "MIT",
55
"author": "João Lenon",
66
"repository": "https://github.com/SecJS/Validator.git",

src/Sanitizer.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,11 @@ export class Sanitizer {
1919
})
2020
}
2121

22-
async sanitize(value, type = 'createSchema', config = {}) {
22+
async sanitize(value, type = 'schema', config = {}) {
2323
if (!this[type]) {
2424
throw new NotImplementedException('Sanitization schema not implemented.')
2525
}
2626

27-
try {
28-
return sanitize(value, this[type](), config)
29-
} catch (error) {
30-
return error
31-
}
27+
return sanitize(value, this[type], config)
3228
}
3329
}

src/Validator.ts

Lines changed: 49 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,57 @@
1-
import { getValue } from 'indicative-utils'
2-
import { NotImplementedException } from '@secjs/exceptions'
31
import {
42
extend,
53
validate,
64
validateAll,
75
validations,
86
} from 'indicative/validator'
97

8+
import { getValue } from 'indicative-utils'
9+
import { VanillaFormatter } from 'indicative-formatters'
10+
import { NotImplementedException } from '@secjs/exceptions'
11+
1012
export class Validator {
13+
get validateAll(): boolean {
14+
return true
15+
}
16+
17+
get removeAdditional(): boolean {
18+
return false
19+
}
20+
21+
get formatter() {
22+
return VanillaFormatter
23+
}
24+
25+
get strictUndefined(): boolean {
26+
return false
27+
}
28+
29+
get messages(): any {
30+
return {}
31+
}
32+
1133
protected validations = validations
1234

35+
private get config() {
36+
return {
37+
formatter: this.formatter,
38+
existyStrict: this.strictUndefined,
39+
removeAdditional: this.removeAdditional
40+
}
41+
}
42+
43+
private resolveDefaults(messages?: any, config?: any) {
44+
if (!messages) messages = {}
45+
46+
messages = { ...messages, ...this.messages }
47+
48+
if (!config) config = {}
49+
50+
config = { ...config, ...this.config }
51+
52+
return { msg: messages, cfg: config }
53+
}
54+
1355
getValue(data: any, field: string) {
1456
return getValue(data, field)
1557
}
@@ -28,27 +70,15 @@ export class Validator {
2870
})
2971
}
3072

31-
async validate(value, type = 'createSchema', messages = {}, config = {}) {
32-
if (!this[type]) {
33-
throw new NotImplementedException('Validation schema not implemented.')
34-
}
35-
36-
try {
37-
await validate(value, this[type](), messages, config)
38-
} catch (error) {
39-
return error
40-
}
41-
}
73+
async validate(value, type = 'schema', messages?: any, config?: any) {
74+
const { msg, cfg } = this.resolveDefaults(messages, config)
4275

43-
async validateAll(value, type = 'createSchema', messages = {}, config = {}) {
4476
if (!this[type]) {
4577
throw new NotImplementedException('Validation schema not implemented.')
4678
}
4779

48-
try {
49-
await validateAll(value, this[type](), messages, config)
50-
} catch (errors) {
51-
return errors
52-
}
80+
if (this.validateAll) return validateAll(value, this[type], msg, cfg)
81+
82+
return validate(value, this[type], msg, cfg)
5383
}
5484
}

tests/sanitizer.spec.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,18 @@ describe('\n Sanitizer', () => {
2020
})
2121
})
2222

23+
it('should throw an error when sanitizer schema does not exist', async () => {
24+
const data = {}
25+
26+
try {
27+
await userSanitizer.sanitize(data, 'undefined-schema')
28+
} catch(error) {
29+
expect(error.status).toBe(501)
30+
expect(error.name).toBe('NotImplementedException')
31+
expect(error.message).toBe('Sanitization schema not implemented.')
32+
}
33+
})
34+
2335
it('should extend sanitization adding escape rule', async () => {
2436
/* eslint no-new: "off" */
2537
new ExtendSanitizer()

tests/stubs/AllFalseValidator.ts

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { Validator } from '../../src/Validator'
2+
3+
export class AllFalseValidator extends Validator {
4+
get validateAll() {
5+
return false
6+
}
7+
8+
get removeAdditional() {
9+
return true
10+
}
11+
12+
get schema() {
13+
return {
14+
name: 'string|required',
15+
email: 'email|required',
16+
}
17+
}
18+
}

tests/stubs/UserSanitizer.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,19 @@
11
import { Sanitizer } from '../../src/Sanitizer'
22

33
export class UserSanitizer extends Sanitizer {
4-
createSchema() {
4+
get schema() {
55
return {
66
email: 'trim|lower_case',
77
}
88
}
99

10-
escapeSchema() {
10+
get escapeSchema() {
1111
return {
1212
email: 'trim|lower_case|escape',
1313
}
1414
}
1515

16-
updateSchema() {
16+
get updateSchema() {
1717
return {
1818
email: 'trim|lower_case',
1919
}

tests/stubs/UserValidator.ts

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,27 @@
11
import { Validator } from '../../src/Validator'
22

33
export class UserValidator extends Validator {
4-
createSchema() {
4+
get schema() {
55
return {
66
name: 'string|required',
77
email: 'email|required',
88
}
99
}
1010

11-
uniqueSchema() {
11+
get messages() {
12+
return {
13+
'name.required': '{{ field }} é obrigatório'
14+
}
15+
}
16+
17+
get uniqueSchema() {
1218
return {
1319
name: 'string|required|unique:users',
1420
email: 'email|required',
1521
}
1622
}
1723

18-
updateSchema() {
24+
get updateSchema() {
1925
return {
2026
name: 'string',
2127
email: 'email',

0 commit comments

Comments
 (0)