vexip-ui
Version:
A Vue 3 UI library, Highly customizability, full TypeScript, performance pretty good
1 lines • 11.5 kB
Source Map (JSON)
{"version":3,"file":"validator.cjs","sources":["../../../components/form/validator.ts"],"sourcesContent":["import { isColor, isDefined, isObject, isPromise, toDate, toNumber } from '@vexip-ui/utils'\n\n// export type Trigger = 'blur' | 'change'\n\nexport type Types =\n | 'string'\n | 'number'\n | 'boolean'\n | 'int'\n | 'float'\n | 'array'\n | 'object'\n | 'date'\n | 'url'\n | 'color'\n | 'email'\ntype Range = [number, number]\ntype ValidatorResult = boolean | string | Error | Promise<boolean | string | Error>\n\nexport interface Rule<T = any> {\n // trigger?: Trigger,\n required?: boolean,\n type?: Types,\n length?: number,\n range?: Range,\n strict?: boolean,\n enums?: T[],\n message?: string,\n validator?(value: T, model: Record<string, any>): ValidatorResult,\n}\n\ntype TypeOptions = Pick<Rule, 'length' | 'range' | 'strict'>\n\nconst DEFAULT_MESSAGE = 'Validate failed'\n\nconst N_100_200 = '1\\\\d\\\\d|2([0-4]\\\\d|5[0-5])'\nconst IPV4_FIRST = `[1-9](\\\\d)?|${N_100_200}`\nconst IPV4_UNIT = `\\\\d{1,2}|${N_100_200}`\nconst IPV4_REG = `(?:${IPV4_FIRST})\\\\.(?:${IPV4_UNIT})\\\\.(?:${IPV4_UNIT})\\\\.(?:${IPV4_UNIT})`\n\nconst HOST_REG = '(?:[a-zA-Z0-9][\\\\w-]*\\\\.)?(?:[a-zA-Z0-9][\\\\w-]*)(?:\\\\.[a-zA-Z]+){1,2}'\nconst PARAM_REG =\n '(?:(?:[\\\\/]+[^\\\\?\\\\.]+)+)?(?:[\\\\/]*)?(\\\\?([^&\\\\.]+=[^&\\\\.]*)(&[^&\\\\.]+=[^&\\\\.]*)*)?(#.*)?'\nconst URL_REG = new RegExp(\n `^(?:[a-z]{2,5}:(\\\\/+)?)?\\\\/\\\\/((?:${IPV4_REG})|(?:${HOST_REG}))(?:${PARAM_REG})?$`,\n)\n\nconst EMAIL_REG = /^(?:[a-zA-Z0-9][\\w-]*)@(?:[a-zA-Z0-9][\\w-]*)(?:\\.[a-zA-Z]+){1,2}$/\n\nconst TYPE_LIST = new Set([\n 'string',\n 'number',\n 'boolean',\n 'int',\n 'float',\n 'array',\n 'object',\n 'date',\n 'url',\n 'color',\n 'email',\n] as Types[])\n\nexport async function validate(\n rules: Rule | Rule[],\n value: unknown,\n model: Record<string, unknown>,\n validateAll = true,\n defaultMsg = DEFAULT_MESSAGE,\n) {\n if (!Array.isArray(rules)) {\n rules = [rules]\n }\n\n const errors: string[] = []\n\n for (const rule of rules as Rule[]) {\n const { message = defaultMsg, validator } = rule\n\n if (typeof validator === 'function') {\n let result\n\n try {\n result = validator(value, model)\n\n if (isPromise(result)) {\n result = await result\n }\n } catch (error) {\n result = error instanceof Error ? error.message : error\n }\n\n if (result !== true) {\n const errorMessage = typeof result === 'string' ? result : message\n\n errors.push(errorMessage)\n\n if (!validateAll) break\n }\n }\n\n if (rule.required && !validateRequirement(value)) {\n errors.push(message)\n\n if (!validateAll) break\n }\n\n if (isDefined(value) && value !== '') {\n if (rule.enums && !validateEnumeration(value, rule.enums)) {\n errors.push(message)\n\n if (!validateAll) break\n }\n\n if (rule.type && !validateType(value, rule.type, rule)) {\n errors.push(message)\n\n if (!validateAll) break\n }\n }\n }\n\n return errors\n}\n\nexport function validateRequirement(value: any) {\n return !(\n !isDefined(value) ||\n value.toString().trim() === '' ||\n (Array.isArray(value) && !value.length) ||\n (isObject(value) && !Object.keys(value).length)\n )\n}\n\nexport function validateEnumeration<T>(value: T | T[], options: T[]) {\n if (!Array.isArray(options) || !options.length) return true\n\n if (Array.isArray(value)) {\n const enumSet = new Set(options)\n\n for (const item of value) {\n if (!enumSet.has(item)) {\n return false\n }\n }\n\n return true\n } else {\n return options.includes(value)\n }\n}\n\nexport function validateType(value: unknown, type: Types, options: TypeOptions = {}) {\n if (!TYPE_LIST.has(type)) return true\n\n switch (type) {\n case 'string':\n return validateString(value, options.length, options.range)\n case 'number':\n return validateNumber(value, options.strict, options.length, options.range)\n case 'boolean':\n return validateBoolean(value, options.strict)\n case 'int':\n return validateInt(value, options.strict, options.length, options.range)\n case 'float':\n return validateFloat(value, options.strict, options.length, options.range)\n case 'array':\n return Array.isArray(value)\n case 'object':\n return isObject(value)\n case 'date':\n return validateDate(value, options.strict)\n case 'url':\n return validateUrl(value)\n case 'color':\n return typeof value === 'string' && isColor(value)\n case 'email':\n return validateEmail(value)\n }\n}\n\nexport function validateString(value: unknown, length?: number, range?: Range) {\n if (typeof value !== 'string') return false\n\n if (isDefined(length) && value.length !== length) {\n return false\n }\n\n if (Array.isArray(range)) {\n const [min, max] = range\n\n if (min && value.length < min) return false\n\n if (max && value.length > max) return false\n }\n\n return true\n}\n\nexport function validateNumber(value: unknown, strict?: boolean, length?: number, range?: Range) {\n if (strict) {\n if (typeof value !== 'number') return false\n } else {\n value = Number(value)\n\n if (Number.isNaN(value)) return false\n }\n\n const number = value as number\n\n if (isDefined(length) && number.toString().length !== length) {\n return false\n }\n\n if (Array.isArray(range)) {\n const [min, max] = range\n\n if (isDefined(min) && number < min) return false\n\n if (isDefined(max) && number > max) return false\n }\n\n return true\n}\n\nexport function validateBoolean(value: unknown, strict?: boolean) {\n if (!strict) {\n if (typeof value === 'string') {\n return value === 'true' || value === 'false'\n }\n\n if (typeof value === 'number') {\n return value === 1 || value === 0\n }\n }\n\n return typeof value === 'boolean'\n}\n\nexport function validateInt(value: unknown, strict?: boolean, length?: number, range?: Range) {\n if (validateNumber(value, strict, length, range)) {\n const number = toNumber(value as any)\n\n return Math.ceil(number) === number\n }\n\n return false\n}\n\nexport function validateFloat(value: unknown, strict?: boolean, length?: number, range?: Range) {\n if (validateNumber(value, strict, length, range)) {\n const number = toNumber(value as any)\n\n return strict ? Math.ceil(number) !== number : number.toString().includes('.')\n }\n\n return false\n}\n\nexport function validateDate(value: unknown, strict?: boolean) {\n if (strict && !(value instanceof Date)) {\n return false\n }\n\n try {\n toDate(value as any)\n } catch (e) {\n return false\n }\n\n return true\n}\n\nexport function validateUrl(value: unknown) {\n return typeof value === 'string' && URL_REG.test(value)\n}\n\nexport function validateEmail(value: unknown) {\n return typeof value === 'string' && EMAIL_REG.test(value)\n}\n"],"names":["DEFAULT_MESSAGE","N_100_200","IPV4_FIRST","IPV4_UNIT","IPV4_REG","HOST_REG","PARAM_REG","URL_REG","EMAIL_REG","TYPE_LIST","validate","rules","value","model","validateAll","defaultMsg","errors","rule","message","validator","result","isPromise","error","errorMessage","validateRequirement","isDefined","validateEnumeration","validateType","isObject","options","enumSet","item","type","validateString","validateNumber","validateBoolean","validateInt","validateFloat","validateDate","validateUrl","isColor","validateEmail","length","range","min","max","strict","number","toNumber","toDate"],"mappings":"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"}