vue-types
Version:
Prop types utility for Vue
603 lines (589 loc) • 17.1 kB
JavaScript
;
Object.defineProperty(exports, '__esModule', { value: true });
const sensibles = require('./shared/vue-types.db27fa20.cjs');
const ObjProto = Object.prototype;
const toString = ObjProto.toString;
const hasOwn = ObjProto.hasOwnProperty;
const FN_MATCH_REGEXP = /^\s*function (\w+)/;
function getType(fn) {
const type = fn?.type ?? fn;
if (type) {
const match = type.toString().match(FN_MATCH_REGEXP);
return match ? match[1] : "";
}
return "";
}
function getNativeType(value) {
if (value === null || value === void 0)
return "";
const match = value.constructor.toString().match(FN_MATCH_REGEXP);
return match ? match[1].replace(/^Async/, "") : "";
}
function deepClone(input) {
if ("structuredClone" in globalThis) {
return structuredClone(input);
}
if (Array.isArray(input)) {
return [...input];
}
if (sensibles.isPlainObject(input)) {
return Object.assign({}, input);
}
return input;
}
function noop() {
}
let warn = noop;
if (process.env.NODE_ENV !== "production") {
const hasConsole = typeof console !== "undefined";
warn = hasConsole ? function warn2(msg, level = sensibles.config.logLevel) {
if (sensibles.config.silent === false) {
console[level](`[VueTypes warn]: ${msg}`);
}
} : noop;
}
const has = (obj, prop) => hasOwn.call(obj, prop);
const isInteger = Number.isInteger || function isInteger2(value) {
return typeof value === "number" && isFinite(value) && Math.floor(value) === value;
};
const isArray = Array.isArray || function isArray2(value) {
return toString.call(value) === "[object Array]";
};
const isFunction = (value) => toString.call(value) === "[object Function]";
const isVueTypeDef = (value, name) => sensibles.isPlainObject(value) && has(value, "_vueTypes_name") && (!name || value._vueTypes_name === name);
const isComplexType = (value) => sensibles.isPlainObject(value) && (has(value, "type") || ["_vueTypes_name", "validator", "default", "required"].some(
(k) => has(value, k)
));
function bindTo(fn, ctx) {
return Object.defineProperty(fn.bind(ctx), "__original", {
value: fn
});
}
function unwrap(fn) {
return fn.__original ?? fn;
}
function validateType(type, value, silent = false) {
let typeToCheck;
let valid = true;
let expectedType = "";
if (!sensibles.isPlainObject(type)) {
typeToCheck = { type };
} else {
typeToCheck = type;
}
const namePrefix = isVueTypeDef(typeToCheck) ? typeToCheck._vueTypes_name + " - " : "";
if (isComplexType(typeToCheck) && typeToCheck.type !== null) {
if (typeToCheck.type === void 0 || typeToCheck.type === true) {
return valid;
}
if (!typeToCheck.required && value == null) {
return valid;
}
if (isArray(typeToCheck.type)) {
valid = typeToCheck.type.some(
(type2) => validateType(type2, value, true) === true
);
expectedType = typeToCheck.type.map((type2) => getType(type2)).join(" or ");
} else {
expectedType = getType(typeToCheck);
if (expectedType === "Array") {
valid = isArray(value);
} else if (expectedType === "Object") {
valid = sensibles.isPlainObject(value);
} else if (expectedType === "String" || expectedType === "Number" || expectedType === "Boolean" || expectedType === "Function") {
valid = getNativeType(value) === expectedType;
} else {
valid = value instanceof typeToCheck.type;
}
}
}
if (!valid) {
const msg = `${namePrefix}value "${value}" should be of type "${expectedType}"`;
if (silent === false) {
warn(msg);
return false;
}
return msg;
}
if (has(typeToCheck, "validator") && isFunction(typeToCheck.validator)) {
const oldWarn = warn;
const warnLog = [];
warn = (msg) => {
warnLog.push(msg);
};
valid = typeToCheck.validator(value);
warn = oldWarn;
if (!valid) {
const msg = (warnLog.length > 1 ? "* " : "") + warnLog.join("\n* ");
warnLog.length = 0;
if (silent === false) {
warn(msg);
return valid;
}
return msg;
}
}
return valid;
}
function toType(name, obj) {
const type = Object.defineProperties(obj, {
_vueTypes_name: {
value: name,
writable: true
},
isRequired: {
get() {
this.required = true;
return this;
}
},
def: {
value(def) {
if (def === void 0) {
if (this.type === Boolean || Array.isArray(this.type) && this.type.includes(Boolean)) {
this.default = void 0;
return;
}
if (has(this, "default")) {
delete this.default;
}
return this;
}
if (!isFunction(def) && validateType(this, def, true) !== true) {
warn(`${this._vueTypes_name} - invalid default value: "${def}"`);
return this;
}
if (isArray(def)) {
this.default = () => deepClone(def);
} else if (sensibles.isPlainObject(def)) {
this.default = () => deepClone(def);
} else {
this.default = def;
}
return this;
}
}
});
const { validator } = type;
if (isFunction(validator)) {
type.validator = bindTo(validator, type);
}
return type;
}
function toValidableType(name, obj) {
const type = toType(name, obj);
return Object.defineProperty(type, "validate", {
value(fn) {
if (isFunction(this.validator)) {
warn(
`${this._vueTypes_name} - calling .validate() will overwrite the current custom validator function. Validator info:
${JSON.stringify(
this
)}`
);
}
this.validator = bindTo(fn, this);
return this;
}
});
}
function clone(obj) {
const descriptors = {};
Object.getOwnPropertyNames(obj).forEach((key) => {
descriptors[key] = Object.getOwnPropertyDescriptor(obj, key);
});
return Object.defineProperties({}, descriptors);
}
function fromType(name, source, props) {
const copy = clone(source);
copy._vueTypes_name = name;
if (!sensibles.isPlainObject(props)) {
return copy;
}
const { validator, ...rest } = props;
if (isFunction(validator)) {
let { validator: prevValidator } = copy;
if (prevValidator) {
prevValidator = unwrap(prevValidator);
}
copy.validator = bindTo(
prevValidator ? function(value, props2) {
return (
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
prevValidator.call(this, value, props2) && validator.call(this, value, props2)
);
} : validator,
copy
);
}
return Object.assign(copy, rest);
}
function indent(string) {
return string.replace(/^(?!\s*$)/gm, " ");
}
const any = () => toValidableType("any", {});
const func = () => toValidableType("function", {
type: Function
});
const bool = () => toValidableType("boolean", {
type: Boolean
});
const string = () => toValidableType("string", {
type: String
});
const number = () => toValidableType("number", {
type: Number
});
const array = () => toValidableType("array", {
type: Array
});
const object = () => toValidableType("object", {
type: Object
});
const integer = () => toType("integer", {
type: Number,
validator(value) {
const res = isInteger(value);
if (res === false) {
warn(`integer - "${value}" is not an integer`);
}
return res;
}
});
const symbol = () => toType("symbol", {
validator(value) {
const res = typeof value === "symbol";
if (res === false) {
warn(`symbol - invalid value "${value}"`);
}
return res;
}
});
const nullable = () => 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.indexOf(value) !== -1;
if (!valid)
warn(msg);
return valid;
}
};
if (arr.indexOf(null) === -1) {
const type = arr.reduce(
(ret, v) => {
if (v !== null && v !== void 0) {
const constr = v.constructor;
ret.indexOf(constr) === -1 && ret.push(constr);
}
return ret;
},
[]
);
if (type.length > 0) {
base.type = type;
}
}
return toType("oneOf", base);
}
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;
}
});
}
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 instanceOf(instanceConstructor) {
return toType("instanceOf", {
type: instanceConstructor
});
}
function objectOf(type) {
return toType("objectOf", {
type: Object,
validator(obj) {
let vResult = "";
if (!sensibles.isPlainObject(obj)) {
return false;
}
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 shape(obj) {
const keys = Object.keys(obj);
const requiredKeys = keys.filter((key) => !!obj[key]?.required);
const type = toType("shape", {
type: Object,
validator(value) {
if (!sensibles.isPlainObject(value)) {
return false;
}
const valueKeys = Object.keys(value);
if (requiredKeys.length > 0 && requiredKeys.some((req) => valueKeys.indexOf(req) === -1)) {
const missing = requiredKeys.filter(
(req) => valueKeys.indexOf(req) === -1
);
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.indexOf(key) === -1) {
if (this._vueTypes_isLoose === true)
return true;
warn(
`shape - shape definition does not include a "${key}" property. Allowed keys: "${keys.join(
'", "'
)}".`
);
return false;
}
const type2 = obj[key];
const valid = validateType(type2, 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;
}
var __defProp = Object.defineProperty;
var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
var __publicField = (obj, key, value) => {
__defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
return value;
};
const BaseVueTypes = /* @__PURE__ */ (() => {
var _a;
return (
// eslint-disable-next-line @typescript-eslint/no-extraneous-class
_a = class {
static get any() {
return any();
}
static get func() {
return func().def(this.defaults.func);
}
static get bool() {
if (this.defaults.bool === void 0) {
return 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 integer() {
return integer().def(this.defaults.integer);
}
static get symbol() {
return symbol();
}
static get nullable() {
return nullable();
}
// eslint-disable-next-line @typescript-eslint/no-unused-vars
static extend(...args) {
warn(
`VueTypes.extend has been removed. Use the ES6+ method instead. See https://dwightjack.github.io/vue-types/advanced/extending-vue-types.html#extending-namespaced-validators-in-es6 for details.`
);
}
}, __publicField(_a, "defaults", {}), __publicField(_a, "sensibleDefaults"), __publicField(_a, "config", sensibles.config), __publicField(_a, "custom", custom), __publicField(_a, "oneOf", oneOf), __publicField(_a, "instanceOf", instanceOf), __publicField(_a, "oneOfType", oneOfType), __publicField(_a, "arrayOf", arrayOf), __publicField(_a, "objectOf", objectOf), __publicField(_a, "shape", shape), __publicField(_a, "utils", {
validate(value, type) {
return validateType(type, value, true) === true;
},
toType(name, obj, validable = false) {
return validable ? toValidableType(name, obj) : toType(name, obj);
}
}), _a
);
})();
function createTypes(defs = sensibles.typeDefaults()) {
var _a;
return _a = class extends BaseVueTypes {
static get sensibleDefaults() {
return { ...this.defaults };
}
static set sensibleDefaults(v) {
if (v === false) {
this.defaults = {};
return;
}
if (v === true) {
this.defaults = { ...defs };
return;
}
this.defaults = { ...v };
}
}, __publicField(_a, "defaults", { ...defs }), _a;
}
class VueTypes extends createTypes() {
}
exports.config = sensibles.config;
exports.any = any;
exports.array = array;
exports.arrayOf = arrayOf;
exports.bool = bool;
exports.createTypes = createTypes;
exports.custom = custom;
exports.default = VueTypes;
exports.fromType = fromType;
exports.func = func;
exports.instanceOf = instanceOf;
exports.integer = integer;
exports.nullable = nullable;
exports.number = number;
exports.object = object;
exports.objectOf = objectOf;
exports.oneOf = oneOf;
exports.oneOfType = oneOfType;
exports.shape = shape;
exports.string = string;
exports.symbol = symbol;
exports.toType = toType;
exports.toValidableType = toValidableType;
exports.validateType = validateType;
//# sourceMappingURL=index.cjs.map