bdn-pocket
Version:
pocket tools for managing redux and redux-saga
104 lines (90 loc) • 2.5 kB
JavaScript
import stampit from '@stamp/it'
import { argOverProp } from '@stamp/arg-over-prop'
import isNil from 'ramda/src/isNil'
import prop from 'ramda/src/prop'
import has from 'ramda/src/has'
export const Type = stampit(argOverProp('required', 'name', 'allowNull'))
.props({
required: true, // key required
type: null,
name: null,
allowNull: false, // null value allowed
})
.methods({
isValid(o = {}, name) {
const propName = name || this.name
const hasProp = has(propName, o)
const v = prop(propName, o)
const isEmpty = isNil(v)
if (this.required) {
if (hasProp === false) {
throw new Error(`prop '${propName}' is required but missing`)
}
}
if (isEmpty === true && this.allowNull === false && hasProp === true) {
throw new Error(`prop '${propName}' does not allow null value`)
}
if (isEmpty === false && this.isTypeOk(v) === false) {
const typeOfV = this.getType(v)
throw new Error(`prop '${propName}' expect type ${this.type} but received ${typeOfV}`)
}
return true
},
/**
* override using Stamp functionality
*
* const newType = Type
* .props({ type: 'newType' })
* .methods({
* isTypeOk(v) {
* return // make your test here
* }
* })
* @param {*} v
*/
isTypeOk(v) {
if (isNil(this.type) === true) return true
return typeof v === this.type
},
getType(v) {
const type = typeof v
if (type === 'object') {
return Array.isArray(v) ? 'array' : 'object'
} else {
return type
}
}
})
export const number = Type.props({ type: 'number' })
export const func = Type.props({ type: 'function' })
export const bool = Type.props({ type: 'boolean' })
export const string = Type.props({ type: 'string' })
export const object = Type.props({ type: 'object' })
.methods({
isTypeOk(v) {
return this.getType(v) === 'object'
// return (typeof v === 'object') && !Array.isArray(v)
}
})
export const array = Type.props({ type: 'array' })
.methods({
isTypeOk(v) {
return this.getType(v) === 'array'
// return Array.isArray(v)
}
})
export const mixed = Type.props({ type: 'mixed' })
.methods({
isTypeOk() { return true }
})
const Types = {
number,
func,
object,
// shape: () => null,
bool,
string,
array,
mixed,
}
export default Types