Skip to content

Commit aab11d1

Browse files
feat(validators): add promise as property resolver
Works with requiredIf and requiredUnless
1 parent 966f1a4 commit aab11d1

File tree

4 files changed

+55
-6
lines changed

4 files changed

+55
-6
lines changed

packages/validators/src/raw/__tests__/requiredIf.spec.js

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@ import requiredIf from '../requiredIf'
22

33
const T = () => true
44
const F = () => false
5+
const promiseT = () => Promise.resolve(true)
6+
const promiseF = () => Promise.resolve(false)
57

68
describe('requiredIf validator', () => {
79
it('should not validate empty string when functional condition is met', () => {
@@ -19,4 +21,18 @@ describe('requiredIf validator', () => {
1921
it('should validate empty string when simple boolean condition not met', () => {
2022
expect(requiredIf('')('')).toBe(true)
2123
})
24+
25+
it('should return a promise when passed a promise condition', () => {
26+
const response = requiredIf(promiseT)('')
27+
expect(response).toHaveProperty('then') // is a promise
28+
})
29+
30+
it('should validate value if condition is a truthy promise', async () => {
31+
expect(await requiredIf(promiseT)('')).toBe(false)
32+
expect(await requiredIf(promiseT)('someValue')).toBe(true)
33+
})
34+
35+
it('should NOT validate value if condition is a falsy promise', async () => {
36+
expect(await requiredIf(promiseF)('')).toBe(true)
37+
})
2238
})
Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,21 @@
11
import { req } from '../common'
2-
import { isTruthy } from '../utils/common'
2+
import { isPromise } from '../utils/common'
33

4-
// TODO: Double check
4+
const validate = (prop, val) => prop ? req(val) : true
5+
/**
6+
* Returns required if the passed property is truthy
7+
* @param {Boolean | String | function(): (Boolean | Promise<boolean>)} prop
8+
* @return {function(*): (Boolean | Promise<Boolean>)}
9+
*/
510
export default (prop) => (value) => {
6-
return isTruthy(prop) ? req(value) : true
11+
if (typeof prop !== 'function') {
12+
return validate(prop, value)
13+
}
14+
const result = prop()
15+
if (isPromise(result)) {
16+
return result.then((response) => {
17+
return validate(response, value)
18+
})
19+
}
20+
return validate(result, value)
721
}
Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,21 @@
11
import { req } from '../common'
2-
import { isTruthy } from '../utils/common'
2+
import { isPromise } from '../utils/common'
33

4-
export default (validateAgainst) => (value) => {
5-
return !isTruthy(validateAgainst) ? req(value) : true
4+
const validate = (prop, val) => !prop ? req(val) : true
5+
/**
6+
* Returns required if the passed property is truthy
7+
* @param {Boolean | String | function(): (Boolean | Promise<boolean>)} prop
8+
* @return {function(*): (Boolean | Promise<Boolean>)}
9+
*/
10+
export default (prop) => (value) => {
11+
if (typeof prop !== 'function') {
12+
return validate(prop, value)
13+
}
14+
const result = prop()
15+
if (isPromise(result)) {
16+
return result.then((response) => {
17+
return validate(response, value)
18+
})
19+
}
20+
return validate(result, value)
621
}

packages/validators/src/utils/common.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,7 @@ export function isTruthy (prop) {
4040
prop = unwrap(prop)
4141
return Boolean(isFunction(prop) ? prop() : prop)
4242
}
43+
44+
export function isPromise (object) {
45+
return isObject(object) && isFunction(object.then)
46+
}

0 commit comments

Comments
 (0)