validierung
Version:
Vue Composition Function for Form Validation
2 lines (1 loc) • 12.6 kB
JavaScript
(function(V){if(!V.VueDemi){var a={},h=V.Vue;if(h)if(h.version.slice(0,2)==="2."){var F=V.VueCompositionAPI;if(F){for(var p in F)a[p]=F[p];a.isVue2=!0,a.isVue3=!1,a.install=function(){},a.Vue=h,a.Vue2=h,a.version=h.version}else console.error("[vue-demi] no VueCompositionAPI instance found, please be sure to import `@vue/composition-api` before `vue-demi`.")}else if(h.version.slice(0,2)==="3."){for(var p in h)a[p]=h[p];a.isVue2=!1,a.isVue3=!0,a.install=function(){},a.Vue=h,a.Vue2=void 0,a.version=h.version,a.set=function(c,y,m){return Array.isArray(c)?(c.length=Math.max(c.length,y),c.splice(y,1,m),m):(c[y]=m,m)},a.del=function(c,y){if(Array.isArray(c)){c.splice(y,1);return}delete c[y]}}else console.error("[vue-demi] Vue version "+h.version+" is unsupported.");else console.error("[vue-demi] no Vue instance found, please be sure to import `vue` before `vue-demi`.");V.VueDemi=a}})(window),function(V,a){"use strict";const h=s=>s!=null,F=s=>c(s)&&!Array.isArray(s),p=s=>Array.isArray(s),c=s=>typeof s=="object"&&s!==null&&!(s instanceof File);function y(s,e){for(const[t,i]of Object.entries(s))c(i)?(e[t]=p(i)?[]:{},y(i,e[t])):e[t]=i}function m(s){if(!c(s))return s;const e=p(s)?[]:{};return y(s,e),e}function K(s,e){let t=e[s[0]];for(let i=0;i<s.length;i++){const l=s[i];if(t==null)return;i>0&&(t=t[l])}return t}function _(s,e,t){if(e.length!==0){for(let i=0;i<e.length-1;i++){const l=e[i],r=e[i+1];s[l]===void 0&&(typeof r=="symbol"||Number.isNaN(+r)?s[l]={}:s[l]=[]),s=s[l]}a.isVue3?s[e[e.length-1]]=t:a.set(s,e[e.length-1],t)}}let C=1;function W(){return C++}function P(s){if(c(s))for(const e of Object.values(s))P(e);if(p(s))for(let e=0;e<s.length;++e)F(s[e])&&!a.isRef(s[e])&&a.reactive(s[e])}function B(s){return a.isVue2&&c(s)&&P(s),a.reactive(s)}function q(s,{wait:e}){let t=null;function i(){clearTimeout(t),t=null}function l(...r){const o=()=>{t=null,s.apply(this,r)};clearTimeout(t),t=setTimeout(o,e)}return l.cancel=i,l}class L{constructor(e){this.next=null,this.prev=null,this.value=e}}class z{constructor(){this.first=null,this.last=null,this.count=0}addFirst(e){const t=new L(e);return this.count===0?(this.first=t,this.last=t):(t.next=this.first,this.first.prev=t,this.first=t),this.count++,t}addLast(e){const t=new L(e);return this.count===0?(this.first=t,this.last=t):(t.prev=this.last,this.last.next=t,this.last=t),this.count++,t}remove(e){this.count!==0&&(e===this.first?this.removeFirst():e===this.last?this.removeLast():(e.prev.next=e.next,e.next.prev=e.prev,e.next=null,e.prev=null,this.count--))}removeFirst(){this.count!==0&&(this.count===1?(this.first=null,this.last=null,this.count--):(this.first=this.first.next,this.first.prev.next=null,this.first.prev=null,this.count--))}removeLast(){this.count!==0&&(this.count===1?(this.first=null,this.last=null,this.count--):(this.last=this.last.prev,this.last.next.prev=null,this.last.next=null,this.count--))}*[Symbol.iterator](){for(let e=this.first;e!==null;e=e.next)yield e}}class G{constructor(){this.isRacing=!1,this.assign()}cancelResolve(e){this.isRacing&&(this.isRacing=!1,this.resolve(e),this.assign())}cancelReject(e){this.isRacing&&(this.isRacing=!1,this.reject(e),this.assign())}race(...e){return this.isRacing=!0,Promise.race([this.promise,...e])}assign(){this.promise=new Promise((e,t)=>{this.resolve=e,this.reject=t})}}class R extends Error{constructor(){super("One or more validation errors occurred")}}const J=s=>typeof s=="function",T=s=>J(s)?[s,void 0]:[s.rule,s.key];class Q{constructor(e,t,i,l,r){this.touched=a.ref(!1),this.dirty=a.ref(!1),this.rulesValidating=a.ref(0),this.validating=a.computed(()=>this.rulesValidating.value>0),this.errors=a.computed(()=>this.rawErrors.value.filter(h)),this.hasError=a.computed(()=>this.hasErrors.value.some(o=>o)),this.simpleValidators=[],this.keyedValidators={},this.form=e,this.uid=t,this.name=i,this.modelValue=a.ref(l),this.rawErrors=a.ref(r.map(()=>null)),this.hasErrors=a.ref(r.map(()=>!1)),this.initialModelValue=m(this.modelValue.value),this.ruleInfos=r.map((o,u)=>{const[n,d]=T(o.rule),f=(b,O,$=this.modelValue,I=!1)=>{if(n&&(I||this.shouldValidate(u,b,O)))return this.validate(u,$)};let M=f,E,g=0,v;o.debounce&&(E=q(b=>{v(this.validate(u,b)),this.rulesValidating.value-=g,this.form.rulesValidating.value-=g,g=0},{wait:o.debounce}),M=(b,O,$=this.modelValue,I=!1)=>{if(n&&(I||this.shouldValidate(u,b,O)))return g++,this.rulesValidating.value++,this.form.rulesValidating.value++,new Promise(se=>{v==null||v(),v=se,E($)})});const S={ruleNumber:u,validator:M,validatorNotDebounced:f};if(d){const b=this.keyedValidators[d];b===void 0?this.keyedValidators[d]=n?[S]:[]:n&&b.push(S)}else this.simpleValidators.push(S);return{buffer:new z,rule:n,validator:M,validatorNotDebounced:f,vbf:o.vbf,cancelDebounce:()=>{E&&(g=0,E.cancel(),v==null||v())}}}),this.watchStopHandle=this.setupWatcher()}async validate(e,t){var i;const{rule:l,buffer:r}=this.ruleInfos[e];let o;const u=a.isRef(t)?l(t.value):l(...t.map(n=>n.value));if(((i=r.last)==null?void 0:i.value)&&(r.last.value=!1,this.rulesValidating.value--,this.form.rulesValidating.value--),typeof(u==null?void 0:u.then)=="function"){const n=r.addLast(!0);this.rulesValidating.value++,this.form.rulesValidating.value++;try{o=await u}catch(d){o=d}if(r.remove(n),n.value)this.rulesValidating.value--,this.form.rulesValidating.value--,this.setError(e,o);else if(typeof o=="string"||typeof o=="symbol")throw o}else o=u,this.setError(e,o)}reset(e=this.initialModelValue){this.watchStopHandle(),this.touched.value=!1,this.dirty.value=!1,this.modelValue.value=m(e),this.rulesValidating.value=0,this.form.rulesValidating.value=0;for(let t=0;t<this.ruleInfos.length;++t){a.isVue3?(this.rawErrors.value[t]=null,this.hasErrors.value[t]=!1):(a.set(this.rawErrors.value,t,null),a.set(this.hasErrors.value,t,!1)),this.ruleInfos[t].cancelDebounce();for(const i of this.ruleInfos[t].buffer)i.value=!1}this.watchStopHandle=this.setupWatcher()}dispose(){a.isVue3&&(this.errors.effect.stop(),this.validating.effect.stop(),this.hasError.effect.stop()),this.watchStopHandle()}shouldValidateForKey(e,t,i){for(let l=0;l<this.keyedValidators[e].length;++l)if(!this.shouldValidate(this.keyedValidators[e][l].ruleNumber,t,i))return!1;return!0}shouldValidate(e,t,i){return this.ruleInfos[e].vbf({hasError:this.rawErrors.value[e]!==null,touched:this.touched.value,dirty:this.dirty.value,force:t,submit:i,value:this.modelValue.value})}setError(e,t){const i=typeof t=="string";if(i||typeof t=="symbol")throw a.isVue3?(i&&(this.rawErrors.value[e]=t),this.hasErrors.value[e]=!0):(i&&a.set(this.rawErrors.value,e,t),a.set(this.hasErrors.value,e,!0)),t;a.isVue3?(this.rawErrors.value[e]=null,this.hasErrors.value[e]=!1):(a.set(this.rawErrors.value,e,null),a.set(this.hasErrors.value,e,!1))}setupWatcher(){return a.watch(this.modelValue,()=>{this.dirty.value=!0,this.form.validate(this.uid)},{deep:!0})}}class U{constructor(){this.simpleMap=new Map,this.keyedMap=new Map,this.reactiveFieldMap=a.shallowReactive(new Map),this.rulesValidating=a.ref(0),this.submitting=a.ref(!1),this.validating=a.computed(()=>this.rulesValidating.value>0),this.hasError=a.computed(()=>this.errors.value.length>0),this.errors=a.computed(()=>{const e=[];for(const t of this.reactiveFieldMap.values())e.push(...t.errors.value);return e})}registerField(e,t,i,l){const r=new Q(this,e,t,i,l),o={rollbacks:[],field:r},u=new Set;return l.forEach(n=>{const d=T(n.rule)[1];if(d){let f=this.keyedMap.get(d);f===void 0?this.keyedMap.set(d,{fields:[r],modelValues:[r.modelValue]}):u.has(d)||(f.fields.push(r),f.modelValues.push(r.modelValue)),f=this.keyedMap.get(d),u.add(d);const M=()=>{let E=-1,g=-1;for(let v=0;v<f.fields.length;++v)f.fields[v]===r&&(E=v),f.modelValues[v]===r.modelValue&&(g=v);E>=0&&f.fields.splice(E,1),g>=0&&f.modelValues.splice(g,1),f.fields.length===0&&this.keyedMap.delete(d)};o.rollbacks.push(M)}}),this.simpleMap.set(e,o),this.reactiveFieldMap.set(e,r),r}validate(e,t=!1){const{field:i}=this.simpleMap.get(e);return Promise.allSettled([...i.simpleValidators.map(({validator:l})=>l(t,!1)),...this.collectValidatorResultsForKeys(i,t,!1)])}async validateAll(e){const t=await Promise.allSettled(this.collectValidatorResultsForNames(e));for(const i of t)if(i.status==="rejected")throw new R}dispose(e){const t=this.simpleMap.get(e);t&&(t.field.dispose(),t.rollbacks.forEach(i=>i())),this.simpleMap.delete(e),this.reactiveFieldMap.delete(e)}resetFields(){for(const{field:e}of this.simpleMap.values())e.reset()}getField(e){const t=this.simpleMap.get(e);if(t)return t.field}*collectValidatorResultsForKeys(e,t,i,l=Object.keys(e.keyedValidators)){for(let r=0;r<l.length;++r){const{fields:o,modelValues:u}=this.keyedMap.get(l[r]);if(this.isEveryOtherFieldTouched(e,o)&&e.shouldValidateForKey(l[r],t,i))for(let n=0;n<o.length;++n){const d=o[n].keyedValidators[l[r]];for(let f=0;f<d.length;++f)yield i?d[f].validatorNotDebounced(t,i,u,o[n]===e):d[f].validator(t,i,u,o[n]===e)}}}*collectValidatorResultsForNames(e){if(e===void 0){for(const{field:t}of this.simpleMap.values()){t.touched.value=!0;for(let i=0;i<t.simpleValidators.length;++i)yield t.simpleValidators[i].validatorNotDebounced(!1,!0)}for(const[t,{fields:i,modelValues:l}]of this.keyedMap.entries())for(let r=0;r<i.length;++r){const o=i[r].keyedValidators[t];for(let u=0;u<o.length;++u)yield o[u].validatorNotDebounced(!1,!0,l)}}else if(e.length>0){const t=new Set(e),i=new Set;for(const{field:l}of this.simpleMap.values())t.has(l.name)&&(l.touched.value=!0);for(const{field:l}of this.simpleMap.values())if(t.has(l.name)){for(let r=0;r<l.simpleValidators.length;++r)yield l.simpleValidators[r].validatorNotDebounced(!1,!0);for(const r of Object.keys(l.keyedValidators))i.has(r)||(i.add(r),yield*this.collectValidatorResultsForKeys(l,!1,!0,[r]))}}}isEveryOtherFieldTouched(e,t){for(let i=0;i<t.length;++i)if(e!==t[i]&&!t[i].touched.value)return!1;return!0}}const X=s=>F(s)?"$value"in s:!1,A=s=>F(s)?"$uid"in s&&"$value"in s:!1;function k(s,e){for(const t of Object.values(e)){if(A(t)){s.dispose(t.$uid);continue}c(t)&&k(s,t)}}function j(s,e,t,i){let l=0;for(const[r,o]of Object.entries(s)){const u=p(s)?+r-l:r,n=A(o),d=n?m(o.$value):a.unref(o);if(i({key:r,value:d,path:t}))e[u]=d;else{++l;continue}n||c(o)&&(e[u]=p(o)?[]:{},j(o,e[u],[...t,r],i))}}function Y(s,e=()=>!0){const t=p(s)?[]:{};return j(s,t,[],e),t}function H(s,e,t){Object.entries(e).forEach(([i,l])=>{const r=t[i];if(A(r)){s.getField(r.$uid).reset(l);return}c(l)&&H(s,l,t[i])})}class Z{constructor(){this.defaultValidationBehavior=null,this.vbfMap=new Map}getDefaultVbf(){return this.defaultValidationBehavior===null?()=>!0:this.vbfMap.get(this.defaultValidationBehavior)}}const w=new Z;function N(s){const e=w.getDefaultVbf();return s.map(t=>{if(typeof t=="function")return{vbf:e,rule:t};if(Array.isArray(t)){const[i,l,r]=t;if(typeof l=="number")return{vbf:e,rule:i,debounce:l};if(typeof i=="function")return{vbf:i,rule:l,debounce:r};const o=w.vbfMap.get(i);if(o!==void 0)return{vbf:o,rule:l,debounce:r}}else return{vbf:e,rule:t}})}function D(s,e,t){const{$value:i,$rules:l,...r}=t,o=l?N(l):[],u=W(),n=s.registerField(u,e,i,o);return{...r,$uid:u,$value:n.modelValue,$errors:n.errors,$hasError:n.hasError,$validating:n.validating,$dirty:n.dirty,$touched:n.touched,async $validate({setTouched:d,force:f}={}){d!=null||(d=!0),f!=null||(f=!0),d&&(n.touched.value=!0),await s.validate(u,f)}}}function x(s,e){for(const[t,i]of Object.entries(e)){if(X(i)){const l=D(s,t,i);e[t]=l;continue}c(i)&&x(s,i)}}function ee(s){const e=new U,t=new G;x(e,s);const i=B(s);return{form:i,submitting:e.submitting,validating:e.validating,hasError:e.hasError,errors:e.errors,async validateFields({names:l,predicate:r}={}){e.submitting.value=!0;const o=Y(i,r);try{await t.race(e.validateAll(l))}finally{e.submitting.value=!1}return o},resetFields(l){t.cancelReject(new R),l===void 0?e.resetFields():H(e,l,i)},add(l,r){const o=l[l.length-1];if(o!==void 0){const u={[o]:r};x(e,u);let n=u[o];const d=K(l,i);a.isVue2&&(n=B(n)),Array.isArray(d)?d.push(n):_(i,l,n)}},remove(l){const r=l.pop();if(r!==void 0)if(l.length===0)k(e,i[r]),a.isVue3?delete i[r]:a.del(i,r);else{const o=K(l,i);if(Array.isArray(o)){const u=o.splice(+r,1);k(e,u)}else k(e,o[r]),a.isVue3?delete o[r]:a.del(o,r)}}}}function te(s){return{install(){var e;for(const[t,i]of Object.entries((e=s.validationBehavior)!=null?e:{}))w.vbfMap.set(t,i);w.vbfMap.has(s.defaultValidationBehavior)&&(w.defaultValidationBehavior=s.defaultValidationBehavior)}}}V.ValidationError=R,V.createValidation=te,V.useValidation=ee,Object.defineProperty(V,"__esModule",{value:!0})}(this.Validierung=this.Validierung||{},VueDemi);