UNPKG

vue-types

Version:
199 lines (181 loc) 5.6 kB
import { isPlainObject } from 'is-plain-object' import { typeDefaults } from './sensibles' import { config } from './config' import { VueTypesDefaults } from './types' export { VueTypeDef, VueTypeValidableDef } from './types' const dfn = Object.defineProperty const isArray = Array.isArray || function (value) { return Object.prototype.toString.call(value) === '[object Array]' } function type<T = any>(name: string, props: any = {}, validable = false): T { const descriptors: PropertyDescriptorMap = { _vueTypes_name: { value: name, writable: true, }, def: { value(v) { // eslint-disable-next-line @typescript-eslint/no-this-alias const t = this if (v === undefined && !t.default) { return t } if (isArray(v)) { t.default = () => [].concat(v) } else if (isPlainObject(v)) { t.default = () => Object.assign({}, v) } else { t.default = v } return t }, }, isRequired: { get() { this.required = true return this }, }, } if (validable) { ;(descriptors as any).validate = { // eslint-disable-next-line @typescript-eslint/no-empty-function value() {}, } } return Object.assign( Object.defineProperties( { validator: () => true, }, descriptors, ), props, ) } export { config } export const any = () => type('any', {}, true) export const func = <T = any>() => type<T>('func', { type: Function }, true) export const bool = () => type('bool', { type: Boolean }, true) export const string = () => type('string', { type: String }, true) export const number = () => type('number', { type: Number }, true) export const array = <T = any>() => type<T>('array', { type: Array }, true) export const object = <T = any>() => type<T>('object', { type: Object }, true) export const symbol = () => type('symbol') export const integer = () => type('integer', { type: Number }) /* eslint-disable @typescript-eslint/no-unused-vars */ export const oneOf = <T = any>(a: any) => type<T>('oneOf') export const custom = <T = any>(a: any) => type<T>('custom') export const instanceOf = <T = any>(Constr: any) => type<T>('instanceOf', { type: Constr }) export const oneOfType = <T = any>(a: any) => type<T>('oneOfType') export const arrayOf = <T = any>(a: any) => type<T>('arrayOf', { type: Array }) export const objectOf = <T = any>(a: any) => type<T>('objectOf', { type: Object }) export const shape = <T = any>(a: any) => dfn( type<T>('shape', { type: Object }), 'loose', { get() { return this }, }, ) /* eslint-enable @typescript-eslint/no-unused-vars */ function createValidator( root: any, name: string, props: any, getter = false, validable = false, ) { const prop = getter ? 'get' : 'value' const descr = { [prop]: () => type(name, props, validable).def( getter ? root.defaults[name] : undefined, ), } return dfn(root, name, descr) } const BaseVueTypes = /*#__PURE__*/ (() => class BaseVueTypes { static defaults: Partial<VueTypesDefaults> = {} static sensibleDefaults: Partial<VueTypesDefaults> | boolean static config = config static get any() { return any() } static get func() { return func().def(this.defaults.func) } static get bool() { return bool().def(this.defaults.bool) } static get string() { return string().def(this.defaults.string) } static get number() { return number().def(this.defaults.number) } static get array() { return array().def(this.defaults.array) } static get object() { return object().def(this.defaults.object) } static get symbol() { return symbol() } static get integer() { return integer().def(this.defaults.integer) } static oneOf = oneOf static custom = custom static instanceOf = instanceOf static oneOfType = oneOfType static arrayOf = arrayOf static objectOf = objectOf static shape = shape static extend<T = any>(props): T { const { name, validate, getter = false, type = null } = props // If we are inheriting from a custom type, let's ignore the type property const extType = isPlainObject(type) && type.type ? null : type return createValidator(this, name, { type: extType }, getter, !!validate) } static utils = { toType: type as (...args: any[]) => any, validate: (...args: any[]) => !!args, } })() export function createTypes(defs: Partial<VueTypesDefaults> = typeDefaults()) { return class extends BaseVueTypes { static defaults = { ...defs } static get sensibleDefaults() { return { ...this.defaults } } static set sensibleDefaults(v: boolean | Partial<VueTypesDefaults>) { if (v === false) { this.defaults = {} return } if (v === true) { this.defaults = { ...defs } return } this.defaults = { ...v } } } } /* eslint-disable no-console */ if (process.env.NODE_ENV !== 'production') { config.silent === false && console.warn( 'You are using the production shimmed version of VueTypes in a development build. Refer to https://dwightjack.github.io/vue-types/guide/installation.html#production-build to learn how to configure VueTypes for usage in multiple environments.', ) } /* eslint-enable no-console */ export default class VueTypes /*#__PURE__*/ extends createTypes() {}