UNPKG

zgg-ui

Version:

2.0.1 正式版本 基于 Vue 3、UniApp 和 TypeScript 开发的多端适配移动端 UI 组件库,旨在提供丰富的组件集合,帮助开发者快速构建多端响应式的移动应用界面

304 lines (277 loc) 7.16 kB
// @ts-nocheck /* eslint no-console:0 */ import type { ValidateError, ValidateOption, RuleValuePackage, InternalRuleItem, SyncErrorType, RuleType, Value, Values, } from './interface' const formatRegExp = /%[sdj%]/g declare var ASYNC_VALIDATOR_NO_WARNING export let warning: (type: string, errors: SyncErrorType[]) => void = () => {} // don't print warning message when in production env or node runtime if ( typeof process !== 'undefined' && process.env && process.env.NODE_ENV !== 'production' && typeof window !== 'undefined' && typeof document !== 'undefined' ) { warning = (type, errors) => { if ( typeof console !== 'undefined' && console.warn && typeof ASYNC_VALIDATOR_NO_WARNING === 'undefined' ) { if (errors.every(e => typeof e === 'string')) { console.warn(type, errors) } } } } export function convertFieldsError( errors: ValidateError[] ): Record<string, ValidateError[]> { if (!errors || !errors.length) return null const fields = {} errors.forEach(error => { const field = error.field fields[field] = fields[field] || [] fields[field].push(error) }) return fields } export function format( template: ((...args: any[]) => string) | string, ...args: any[] ): string { let i = 0 const len = args.length if (typeof template === 'function') { return template.apply(null, args) } if (typeof template === 'string') { let str = template.replace(formatRegExp, x => { if (x === '%%') { return '%' } if (i >= len) { return x } switch (x) { case '%s': return String(args[i++]) case '%d': return Number(args[i++]) as unknown as string case '%j': try { return JSON.stringify(args[i++]) } catch (_) { return '[Circular]' } break default: return x } }) return str } return template } function isNativeStringType(type: string) { return ( type === 'string' || type === 'url' || type === 'hex' || type === 'email' || type === 'date' || type === 'pattern' ) } export function isEmptyValue(value: Value, type?: string) { if (value === undefined || value === null) { return true } if (type === 'array' && Array.isArray(value) && !value.length) { return true } if (isNativeStringType(type) && typeof value === 'string' && !value) { return true } return false } export function isEmptyObject(obj: object) { return Object.keys(obj).length === 0 } function asyncParallelArray( arr: RuleValuePackage[], func: ValidateFunc, callback: (errors: ValidateError[]) => void ) { const results: ValidateError[] = [] let total = 0 const arrLength = arr.length function count(errors: ValidateError[]) { results.push(...(errors || [])) total++ if (total === arrLength) { callback(results) } } arr.forEach(a => { func(a, count) }) } function asyncSerialArray( arr: RuleValuePackage[], func: ValidateFunc, callback: (errors: ValidateError[]) => void ) { let index = 0 const arrLength = arr.length function next(errors: ValidateError[]) { if (errors && errors.length) { callback(errors) return } const original = index index = index + 1 if (original < arrLength) { func(arr[original], next) } else { callback([]) } } next([]) } function flattenObjArr(objArr: Record<string, RuleValuePackage[]>) { const ret: RuleValuePackage[] = [] Object.keys(objArr).forEach(k => { ret.push(...(objArr[k] || [])) }) return ret } export class AsyncValidationError extends Error { errors: ValidateError[] fields: Record<string, ValidateError[]> constructor(errors: ValidateError[], fields: Record<string, ValidateError[]>) { super('Async Validation Error') this.errors = errors this.fields = fields } } type ValidateFunc = ( data: RuleValuePackage, doIt: (errors: ValidateError[]) => void ) => void export function asyncMap( objArr: Record<string, RuleValuePackage[]>, option: ValidateOption, func: ValidateFunc, callback: (errors: ValidateError[]) => void, source: Values ): Promise<Values> { if (option.first) { const pending = new Promise<Values>((resolve, reject) => { const next = (errors: ValidateError[]) => { callback(errors) return errors.length ? reject(new AsyncValidationError(errors, convertFieldsError(errors))) : resolve(source) } const flattenArr = flattenObjArr(objArr) asyncSerialArray(flattenArr, func, next) }) pending.catch(e => e) return pending } const firstFields = option.firstFields === true ? Object.keys(objArr) : option.firstFields || [] const objArrKeys = Object.keys(objArr) const objArrLength = objArrKeys.length let total = 0 const results: ValidateError[] = [] const pending = new Promise<Values>((resolve, reject) => { const next = (errors: ValidateError[]) => { results.push.apply(results, errors) total++ if (total === objArrLength) { callback(results) return results.length ? reject(new AsyncValidationError(results, convertFieldsError(results))) : resolve(source) } } if (!objArrKeys.length) { callback(results) resolve(source) } objArrKeys.forEach(key => { const arr = objArr[key] if (firstFields.indexOf(key) !== -1) { asyncSerialArray(arr, func, next) } else { asyncParallelArray(arr, func, next) } }) }) pending.catch(e => e) return pending } function isErrorObj( obj: ValidateError | string | (() => string) ): obj is ValidateError { return !!(obj && (obj as ValidateError).message !== undefined) } function getValue(value: Values, path: string[]) { let v = value for (let i = 0; i < path.length; i++) { if (v == undefined) { return v } v = v[path[i]] } return v } export function complementError(rule: InternalRuleItem, source: Values) { return (oe: ValidateError | (() => string) | string): ValidateError => { let fieldValue if (rule.fullFields) { fieldValue = getValue(source, rule.fullFields) } else { fieldValue = source[(oe as any).field || rule.fullField] } if (isErrorObj(oe)) { oe.field = oe.field || rule.fullField oe.fieldValue = fieldValue return oe } return { message: typeof oe === 'function' ? oe() : oe, fieldValue, field: (oe as unknown as ValidateError).field || rule.fullField, } } } export function deepMerge<T extends object>(target: T, source: Partial<T>): T { if (source) { for (const s in source) { if (source.hasOwnProperty(s)) { const value = source[s] if (typeof value === 'object' && typeof target[s] === 'object') { target[s] = { ...target[s], ...value, } } else { target[s] = value } } } } return target }