@antdv/pro-utils
Version:
@antdv/pro-utils
290 lines (289 loc) • 7.01 kB
JavaScript
import { isArray, isFunction } from "../is/index.mjs";
import {
indent,
isComplexType,
isPlainObject,
isVueTypeDef,
toType,
toValidateType,
validateType,
warn
} from "./utils.mjs";
const anyType = () => toValidateType("any", {});
const vNodeType = () => toValidateType("vnode", {});
function funcType() {
return toValidateType("function", {
type: Function
});
}
function boolType() {
return toValidateType("boolean", {
type: Boolean
});
}
function stringType() {
return toValidateType("string", {
type: String
});
}
function numberType() {
return toValidateType("number", {
type: Number
});
}
function arrayType() {
return toValidateType("array", {
type: Array
});
}
function arrayOf(type) {
return toType("arrayOf", {
type: Array,
validator(values) {
let vResult = "";
const valid = values.every((value) => {
vResult = validateType(type, value, true);
return vResult === true;
});
if (!valid) {
warn(`arrayOf - value validation error:
${indent(vResult)}`);
}
return valid;
}
});
}
function objectType() {
return toValidateType("object", {
type: Object
});
}
function objectOf(type) {
return toType("objectOf", {
type: Object,
validator(obj) {
let vResult = "";
const valid = Object.keys(obj).every((key) => {
vResult = validateType(type, obj[key], true);
return vResult === true;
});
if (!valid) {
warn(`objectOf - value validation error:
${indent(vResult)}`);
}
return valid;
}
});
}
function symbol() {
return toType("symbol", {
validator(value) {
const res = typeof value === "symbol";
if (res === false) {
warn(`symbol - invalid value "${value}"`);
}
return res;
}
});
}
function nullable() {
return Object.defineProperty(
{
type: null,
validator(value) {
const res = value === null;
if (res === false) {
warn(`nullable - value should be null`);
}
return res;
}
},
"_vueTypes_name",
{ value: "nullable" }
);
}
function custom(validatorFn, warnMsg = "custom validation failed") {
if (typeof validatorFn !== "function") {
throw new TypeError(
"[VueTypes error]: You must provide a function as argument"
);
}
return toType(validatorFn.name || "<<anonymous function>>", {
type: null,
validator(value) {
const valid = validatorFn(value);
if (!valid) warn(`${this._vueTypes_name} - ${warnMsg}`);
return valid;
}
});
}
function oneOf(arr) {
if (!isArray(arr)) {
throw new TypeError(
"[VueTypes error]: You must provide an array as argument."
);
}
const msg = `oneOf - value should be one of "${arr.map((v) => typeof v === "symbol" ? v.toString() : v).join('", "')}".`;
const base = {
validator(value) {
const valid = arr.includes(value);
if (!valid) warn(msg);
return valid;
}
};
if (!arr.includes(null)) {
const type = arr.reduce(
(ret, v) => {
if (v !== null && v !== void 0) {
const constr = v.constructor;
!ret.includes(constr) && ret.push(constr);
}
return ret;
},
[]
);
if (type.length > 0) {
base.type = type;
}
}
return toType("oneOf", base);
}
function shape(obj) {
const keys = Object.keys(obj);
const requiredKeys = keys.filter((key) => {
var _a;
return !!((_a = obj[key]) == null ? void 0 : _a.required);
});
const type = toType("shape", {
type: Object,
validator(value) {
if (!isPlainObject(value)) {
return false;
}
const valueKeys = Object.keys(value);
if (requiredKeys.length > 0 && requiredKeys.some((req) => !valueKeys.includes(req))) {
const missing = requiredKeys.filter(
(req) => !valueKeys.includes(req)
);
if (missing.length === 1) {
warn(`shape - required property "${missing[0]}" is not defined.`);
} else {
warn(
`shape - required properties "${missing.join(
'", "'
)}" are not defined.`
);
}
return false;
}
return valueKeys.every((key) => {
if (!keys.includes(key)) {
if (this._vueTypes_isLoose === true)
return true;
warn(
`shape - shape definition does not include a "${key}" property. Allowed keys: "${keys.join(
'", "'
)}".`
);
return false;
}
const _type = obj[key];
const valid = validateType(_type, value[key], true);
if (typeof valid === "string") {
warn(`shape - "${key}" property validation error:
${indent(valid)}`);
}
return valid === true;
});
}
});
Object.defineProperty(type, "_vueTypes_isLoose", {
writable: true,
value: false
});
Object.defineProperty(type, "loose", {
get() {
this._vueTypes_isLoose = true;
return this;
}
});
return type;
}
function oneOfType(arr) {
if (!isArray(arr)) {
throw new TypeError(
"[VueTypes error]: You must provide an array as argument"
);
}
let hasCustomValidators = false;
let hasNullable = false;
let nativeChecks = [];
for (let i = 0; i < arr.length; i += 1) {
const type = arr[i];
if (isComplexType(type)) {
if (isFunction(type.validator)) {
hasCustomValidators = true;
}
if (isVueTypeDef(type, "oneOf") && type.type) {
nativeChecks = nativeChecks.concat(type.type);
continue;
}
if (isVueTypeDef(type, "nullable")) {
hasNullable = true;
continue;
}
if (type.type === true || !type.type) {
warn('oneOfType - invalid usage of "true" and "null" as types.');
continue;
}
nativeChecks = nativeChecks.concat(type.type);
} else {
nativeChecks.push(type);
}
}
nativeChecks = nativeChecks.filter((t, i) => nativeChecks.indexOf(t) === i);
const typeProp = hasNullable === false && nativeChecks.length > 0 ? nativeChecks : null;
if (!hasCustomValidators) {
return toType("oneOfType", {
type: typeProp
});
}
return toType("oneOfType", {
type: typeProp,
validator(value) {
const err = [];
const valid = arr.some((type) => {
const res = validateType(type, value, true);
if (typeof res === "string") {
err.push(res);
}
return res === true;
});
if (!valid) {
warn(
`oneOfType - provided value does not match any of the ${err.length} passed-in validators:
${indent(err.join("\n"))}`
);
}
return valid;
}
});
}
export {
anyType,
arrayOf,
arrayType,
boolType,
custom,
funcType,
nullable,
numberType,
objectOf,
objectType,
oneOf,
oneOfType,
shape,
stringType,
symbol,
vNodeType
};